Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Menemukan pengguna unik dari nilai yang ditautkan

Ingin ikut serta dengan opsi untuk menyelesaikan tugas Anda dengan BigQuery (SQL Standar) murni

Prasyarat / asumsi :sumber data ada di sandbox.temp.id1_id2_pairs
Anda harus mengganti ini dengan milik Anda sendiri atau jika Anda ingin menguji dengan data dummy dari pertanyaan Anda - Anda dapat membuat tabel ini seperti di bawah ini (tentu saja ganti sandbox.temp dengan project.dataset Anda sendiri )


Pastikan Anda mengatur tabel tujuan masing-masing

Catatan :Anda dapat menemukan semua Pertanyaan masing-masing (sebagai teks) di bagian bawah jawaban ini, tetapi untuk saat ini saya menggambarkan jawaban saya dengan tangkapan layar - jadi semuanya disajikan - kueri, hasil, dan opsi yang digunakan

Jadi, akan ada tiga langkah:

Langkah 1 - Inisialisasi

Disini kita hanya melakukan pengelompokan awal id1 berdasarkan koneksi dengan id2:

Seperti yang Anda lihat di sini - kami membuat daftar semua nilai id1 dengan koneksi masing-masing berdasarkan koneksi satu tingkat sederhana melalui id2

Tabel keluaran adalah sandbox.temp.groups

Langkah 2 - Mengelompokkan Iterasi

Dalam setiap iterasi kita akan memperkaya pengelompokan berdasarkan grup yang sudah terbentuk.
Sumber Query adalah tabel keluaran dari Langkah sebelumnya (sandbox.temp.groups ) dan Destination adalah tabel yang sama (sandbox.temp.groups ) dengan Timpa

Kami akan melanjutkan iterasi sampai jumlah grup yang ditemukan akan sama seperti pada iterasi sebelumnya

Catatan :Anda cukup membuka dua Tab UI Web BigQuery (seperti yang ditunjukkan di atas) dan tanpa mengubah kode apa pun, jalankan Pengelompokan, lalu Periksa lagi dan lagi hingga iterasi menyatu

(untuk data spesifik yang saya gunakan di bagian prasyarat - Saya memiliki tiga iterasi - iterasi pertama menghasilkan 5 pengguna, iterasi kedua menghasilkan 3 pengguna dan iterasi ketiga menghasilkan lagi 3 pengguna - yang menunjukkan bahwa kami selesai dengan iterasi.

Tentu saja, dalam kasus kehidupan nyata - jumlah iterasi bisa lebih dari hanya tiga - jadi kami memerlukan semacam otomatisasi (lihat bagian masing-masing di bagian bawah jawaban).

Langkah 3 – Pengelompokan Akhir
Ketika pengelompokan id1 selesai - kita dapat menambahkan pengelompokan akhir untuk id2

Hasil akhir sekarang ada di sandbox.temp.users tabel

Kueri yang Digunakan (jangan lupa untuk mengatur tabel tujuan masing-masing dan menimpa bila diperlukan sesuai logika dan tangkapan layar yang dijelaskan di atas):

Prasyarat:

#standardSQL
SELECT 1 id, 'e1' id1, 'm1' id2 UNION ALL
SELECT 2,    'e1',     'm2' UNION ALL
SELECT 3,    'e2',     'm2' UNION ALL
SELECT 4,    'e3',     'm1' UNION ALL
SELECT 5,    'e4',     'm3' UNION ALL
SELECT 6,    'e5',     'm3' UNION ALL
SELECT 7,    'e5',     'm4' UNION ALL
SELECT 8,    'e4',     'm5' UNION ALL
SELECT 9,    'e6',     'm6' UNION ALL
SELECT 9,    'e7',     'm7' UNION ALL
SELECT 9,    'e2',     'm6' UNION ALL
SELECT 888,  'e4',     'm55'   

Langkah 1

#standardSQL
WITH `yourTable` AS (select * from `sandbox.temp.id1_id2_pairs`
), x1 AS (SELECT id1, STRING_AGG(id2) id2s FROM `yourTable` GROUP BY id1
), x2 AS (SELECT id2, STRING_AGG(id1) id1s FROM `yourTable` GROUP BY id2 
), x3 AS (
  SELECT id, (SELECT STRING_AGG(i ORDER BY i) FROM (
    SELECT DISTINCT i FROM UNNEST(SPLIT(id1s)) i)) grp
  FROM (
    SELECT x1.id1 id, STRING_AGG((id1s)) id1s FROM x1 CROSS JOIN x2
    WHERE EXISTS (SELECT y FROM UNNEST(SPLIT(id1s)) y WHERE x1.id1 = y)
    GROUP BY id1) 
)
SELECT * FROM x3 

Langkah 2 - Pengelompokan

#standardSQL
WITH x3 AS (select * from `sandbox.temp.groups`)
SELECT id, (SELECT STRING_AGG(i ORDER BY i) FROM (
  SELECT DISTINCT i FROM UNNEST(SPLIT(grp)) i)) grp
FROM (
  SELECT a.id, STRING_AGG(b.grp) grp FROM x3 a CROSS JOIN x3 b 
  WHERE EXISTS (SELECT y FROM UNNEST(SPLIT(b.grp)) y WHERE a.id = y)
  GROUP BY a.id )   

Langkah 2 - Periksa

#standardSQL
SELECT COUNT(DISTINCT grp) users FROM `sandbox.temp.groups` 

Langkah 3

#standardSQL
WITH `yourTable` AS (select * from `sandbox.temp.id1_id2_pairs`
), x1 AS (SELECT id1, STRING_AGG(id2) id2s FROM `yourTable` GROUP BY id1 
), x3 as (select * from `sandbox.temp.groups`
), f  AS (SELECT DISTINCT grp FROM x3 ORDER BY grp
)
SELECT ROW_NUMBER() OVER() id, grp id1, 
  (SELECT STRING_AGG(i ORDER BY i) FROM (SELECT DISTINCT i FROM UNNEST(SPLIT(id2)) i)) id2
FROM (
  SELECT grp, STRING_AGG(id2s) id2 FROM f 
  CROSS JOIN x1 WHERE EXISTS (SELECT y FROM UNNEST(SPLIT(f.grp)) y WHERE id1 = y)
  GROUP BY grp)

Otomasi :
Tentu saja, "proses" di atas dapat dijalankan secara manual untuk berjaga-jaga jika iterasi berkumpul dengan cepat - jadi Anda akan berakhir dengan 10-20 kali. Namun dalam kasus kehidupan nyata lainnya, Anda dapat dengan mudah mengotomatiskannya dengan klien mana pun pilihan Anda




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Batasi nilai tipe data MySQL ke rentang tertentu (sebaiknya bukan ENUM)

  2. Cara Menginstal dan Mengkonfigurasi phpMyAdmin di Debian 8

  3. hive.HiveImport:GAGAL:SemanticException [Kesalahan 10072]:Basis data tidak ada:

  4. Rails:mysql &postgres secara bersamaan di aplikasi yang sama?

  5. Bagaimana mencegah mysqldump membagi dump menjadi peningkatan 1MB?