Ke UNION
baris yang dihasilkan dari ketiga kueri lalu pilih 5 baris dengan amount
tertinggi :
(SELECT event_id, count(*) AS amount
FROM pageview
GROUP BY event_id
ORDER BY pageviews DESC, rand()
LIMIT 1000)
UNION ALL
(SELECT event_id, count(*)
FROM upvote
GROUP BY event_id
ORDER BY upvotes DESC, rand()
LIMIT 1000)
UNION ALL
(SELECT event_id, count(*)
FROM attending
GROUP BY event_id
ORDER BY attendants DESC, rand()
LIMIT 1000)
ORDER BY 2 DESC
LIMIT 5;
UNION ALL
untuk menyimpan duplikat.
Untuk menambahkan hitungan untuk setiap event_id
:
SELECT event_id, sum(amount) AS total
FROM (
(SELECT event_id, count(*) AS amount
FROM pageview
GROUP BY event_id
ORDER BY pageviews DESC, rand()
LIMIT 1000)
UNION ALL
(SELECT event_id, count(*)
FROM upvote
GROUP BY event_id
ORDER BY upvotes DESC, rand()
LIMIT 1000)
UNION ALL
(SELECT event_id, count(*)
FROM attending
GROUP BY event_id
ORDER BY attendants DESC, rand()
LIMIT 1000)
) x
GROUP BY 1
ORDER BY sum(amount) DESC
LIMIT 5;
Bagian yang sulit di sini adalah tidak setiap event_id
akan hadir di ketiga kueri dasar. Jadi berhati-hatilah agar JOIN
tidak kehilangan baris sepenuhnya dan penambahan tidak menghasilkan NULL
.
Gunakan UNION ALL
, bukan UNION
. Anda tidak ingin menghapus baris yang identik, Anda ingin menambahkannya.
x
adalah alias tabel dan singkatan untuk AS x
. Diperlukan agar subquery memiliki nama. Bisa nama lain apa saja di sini.
Fitur SOL FULL OUTER JOIN
tidak diimplementasikan di MySQL (terakhir kali saya periksa), jadi Anda harus puas dengan UNION
. FULL OUTER JOIN
akan menggabungkan ketiga kueri dasar tanpa kehilangan baris.
Jawaban untuk pertanyaan lanjutan
SELECT event_id, sum(amount) AS total
FROM (
(SELECT event_id, count(*) / 100 AS amount
FROM pageview ... )
UNION ALL
(SELECT event_id, count(*) * 5
FROM upvote ... )
UNION ALL
(SELECT event_id, count(*) * 10
FROM attending ... )
) x
GROUP BY 1
ORDER BY sum(amount) DESC
LIMIT 5;
Atau, untuk menggunakan hitungan dasar dalam berbagai cara:
SELECT event_id
,sum(CASE source
WHEN 'p' THEN amount / 100
WHEN 'u' THEN amount * 5
WHEN 'a' THEN amount * 10
ELSE 0
END) AS total
FROM (
(SELECT event_id, 'p'::text AS source, count(*) AS amount
FROM pageview ... )
UNION ALL
(SELECT event_id, 'u'::text, count(*)
FROM upvote ... )
UNION ALL
(SELECT event_id, 'a'::text, count(*)
FROM attending ... )
) x
GROUP BY 1
ORDER BY 2 DESC
LIMIT 5;