Do UNION
wynikowe wiersze wszystkich trzech zapytań, a następnie wybierz 5 wierszy z najwyższą 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
aby zachować duplikaty.
Aby dodać liczniki dla każdego 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;
Trudne jest to, że nie każdy event_id
będzie obecny we wszystkich trzech zapytaniach bazowych. Uważaj więc, aby JOIN
nie traci wierszy całkowicie, a dodawania nie wychodzą NULL
.
Użyj UNION ALL
, a nie UNION
. Nie chcesz usuwać identycznych wierszy, chcesz je dodać.
x
to alias tabeli i skrót dla AS x
. Podzapytanie musi mieć nazwę. Tutaj może być dowolna inna nazwa.
Funkcja SOL FULL OUTER JOIN
nie jest zaimplementowany w MySQL (ostatnio sprawdzałem), więc musisz zadowolić się UNION
. FULL OUTER JOIN
dołączyłby do wszystkich trzech zapytań podstawowych bez utraty wierszy.
Odpowiedź na pytanie uzupełniające
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;
Lub, aby użyć liczników bazowych na wiele sposobów:
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;