Naar UNION
de resulterende rijen van alle drie de zoekopdrachten en kies vervolgens de 5 rijen met het hoogste 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
om duplicaten te bewaren.
Om de tellingen toe te voegen voor elke 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;
Het lastige hier is dat niet elke event_id
zal aanwezig zijn in alle drie de basisquery's. Zorg er dus voor dat een JOIN
verliest rijen niet volledig en toevoegingen worden niet NULL
.
Gebruik UNION ALL
, niet UNION
. U wilt identieke rijen niet verwijderen, u wilt ze optellen.
x
is een tabelalias en afkorting voor AS x
. Een subquery moet een naam hebben. Kan hier elke andere naam zijn.
De SOL-functie FULL OUTER JOIN
is niet geïmplementeerd in MySQL (laatste keer dat ik het controleerde), dus je moet het doen met UNION
. FULL OUTER JOIN
zou deelnemen aan alle drie de basisquery's zonder rijen te verliezen.
Antwoord op vervolgvraag
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;
Of, om de basistellingen op meerdere manieren te gebruiken:
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;