Techniquement, votre requête pourrait fonctionner comme ceci (pas tout à fait sûr de l'objectif de cette requête) :
SELECT 9 AS keyword_id, count(DISTINCT m.id) AS total, t.parent_id AS tag_id
FROM (
SELECT unnest(m.taglist) AS tag_id
FROM mentions m
WHERE m.search_id = 3
AND 9 = ANY (m.taglist)
) m
JOIN tags t USING (tag_id) -- assumes tag.tag_id!
GROUP BY t.parent_id;
Cependant, il me semble que vous allez dans la mauvaise direction ici. Normalement, on supprimerait le tableau redondant taglist
et conserver le schéma de base de données normalisé. Ensuite, votre requête d'origine devrait bien servir, seulement raccourcir la syntaxe avec des alias :
SELECT 9 AS keyword_id, count(DISTINCT m.id) AS total, t.parent_id AS tag_id
FROM mentions m
JOIN taggings mt ON mt.mention_id = m.id
JOIN tags t ON t.id = mt.tag_id
WHERE 9 = ANY (m.taglist)
AND m.search_id = 3
GROUP BY t.parent_id;
Percez le mystère
<rant>
La cause première de vos "résultats différents" est la convention de dénomination malheureuse que certains ORM intellectuellement défiés imposer aux gens.
Je parle de
comme nom de colonne. N'utilisez jamais cet anti-modèle dans une base de données avec plus d'une table. D'accord, cela signifie essentiellement tout base de données. Dès que vous rejoignez un groupe de tables (c'est ce que vous faites dans une base de données) vous vous retrouvez avec un tas de colonnes nommées idid
. Complètement inutile.
La colonne ID d'une table nommée tag
devrait être tag_id
(sauf s'il existe un autre nom descriptif). Jamais id
.</rant>
Votre requête compte par inadvertance les tags
au lieu de mentions
:
SELECT 25 AS keyword_id, count(m.id) AS total, t.parent_id AS tag_id
FROM (
SELECT unnest(m.taglist) AS id
FROM mentions m
WHERE m.search_id = 4
AND 25 = ANY (m.taglist)
) m
JOIN tags t USING (id)
GROUP BY t.parent_id;
Cela devrait fonctionner comme suit :
SELECT 25 AS keyword_id, count(DISTINCT m.id) AS total, t.parent_id
FROM (
SELECT m.id, unnest(m.taglist) AS tag_id
FROM mentions m
WHERE m.search_id = 4
AND 25 = ANY (m.taglist)
) m
JOIN tags t ON t.id = m.tag_id
GROUP BY t.parent_id;
J'ai également rajouté le DISTINCT
à votre count()
qui s'est perdu en cours de route dans votre requête.