Til UNION
de resulterende rækker af alle tre forespørgsler, og vælg derefter de 5 rækker med det højeste 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
for at beholde dubletter.
At tilføje tæller for hver 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;
Den vanskelige del her er, at ikke alle event_id
vil være til stede i alle tre basisforespørgsler. Så sørg for, at en JOIN
mister ikke rækker fuldstændigt, og tilføjelser bliver ikke NULL
.
Brug UNION ALL
, ikke UNION
. Du ønsker ikke at fjerne identiske rækker, du vil tilføje dem.
x
er et tabelalias og en forkortelse for AS x
. Det er påkrævet, for at en underforespørgsel skal have et navn. Kan være et hvilket som helst andet navn her.
SOL-funktionen FULL OUTER JOIN
er ikke implementeret i MySQL (sidste gang jeg tjekkede), så du må nøjes med UNION
. FULL OUTER JOIN
ville forbinde alle tre basisforespørgsler uden at miste rækker.
Svar på opfølgende spørgsmål
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;
Eller for at bruge basistællingerne på flere måder:
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;