Vers UNION
les lignes résultantes des trois requêtes, puis choisissez les 5 lignes avec le amount
le plus élevé :
(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
pour conserver les doublons.
Pour ajouter les décomptes pour chaque 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;
La partie délicate ici est que tous les event_id
sera présent dans les trois requêtes de base. Veillez donc à ce qu'un JOIN
ne perd pas complètement les lignes et les ajouts ne s'avèrent pas NULL
.
Utilisez UNION ALL
, pas UNION
. Vous ne voulez pas supprimer des lignes identiques, vous voulez les additionner.
x
est un alias de table et un raccourci pour AS x
. Il est nécessaire qu'une sous-requête ait un nom. Peut être n'importe quel autre nom ici.
La fonctionnalité SOL FULL OUTER JOIN
n'est pas implémenté dans MySQL (la dernière fois que j'ai vérifié), vous devez donc vous contenter de UNION
. FULL OUTER JOIN
rejoindrait les trois requêtes de base sans perdre de lignes.
Réponse à la question complémentaire
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, pour utiliser les décomptes de base de plusieurs manières :
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;