Para
UNION
as linhas resultantes de todas as três consultas e, em seguida, escolha as 5 linhas com o maior 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;
O manual:
UNION ALL
para manter duplicatas. Para adicionar as contagens para cada
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;
A parte complicada aqui é que nem todo
event_id
estará presente em todas as três consultas básicas. Portanto, tome cuidado para que um JOIN
não perde linhas completamente e as adições não resultam em NULL
. Use
UNION ALL
, não UNION
. Você não deseja remover linhas idênticas, deseja adicioná-las. x
é um alias de tabela e um atalho para AS x
. É necessário para que uma subconsulta tenha um nome. Pode ser qualquer outro nome aqui. O recurso SOL
FULL OUTER JOIN
não está implementado no MySQL (da última vez que verifiquei), então você precisa se contentar com UNION
. FULL OUTER JOIN
juntaria todas as três consultas básicas sem perder linhas. Resposta à pergunta complementar
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;
Ou, para usar as contagens de base de várias maneiras:
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;