Към UNION
получените редове от всичките три заявки и след това изберете 5-те реда с най-висока amount
:
(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
за запазване на дубликати.
За добавяне на броя за всеки 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;
Трудната част тук е, че не всеки event_id
ще присъства и в трите основни заявки. Затова се погрижете за JOIN
не губи напълно редове и добавянията не се оказват NULL
.
Използвайте UNION ALL
, а не UNION
. Не искате да премахвате идентични редове, искате да ги добавяте.
x
е псевдоним на таблица и съкращаване на AS x
. Изисква се подзаявката да има име. Тук може да бъде всяко друго име.
Функцията SOL FULL OUTER JOIN
не е внедрен в MySQL (последния път, когато проверих), така че трябва да се справите с UNION
. FULL OUTER JOIN
ще се присъедини към трите основни заявки, без да губи редове.
Отговор на последващ въпрос
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;
Или, за да използвате основния брой по няколко начина:
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;