Technisch gezien zou uw zoekopdracht als volgt kunnen werken (niet helemaal zeker over het doel van deze zoekopdracht):
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;
Het lijkt me echter dat je hier de verkeerde kant op gaat. Normaal gesproken zou men de redundante array taglist
. verwijderen en behoud het genormaliseerde databaseschema. Dan zou je oorspronkelijke zoekopdracht goed moeten werken, alleen de syntaxis verkort met aliassen:
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;
Ontrafel het mysterie
<rant>
De hoofdoorzaak voor uw "verschillende resultaten" is de ongelukkige naamgevingsconventie die sommige intellectueel uitgedaagde ORM's mensen opleggen.
Ik heb het over
als kolomnaam. Gebruik dit anti-patroon nooit in een database met meer dan één tabel. Juist, dat betekent in feite elke databank. Zodra je aan een aantal tafels deelneemt (dat is wat je doe in een database) krijg je een aantal kolommen met de naam idid
. Volkomen zinloos.
De ID-kolom van een tabel met de naam tag
moet tag_id
. zijn (tenzij er een andere beschrijvende naam is). Nooit id
.</rant>
Uw zoekopdracht telt per ongeluk tags
in plaats van 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;
Het zou op deze manier moeten werken:
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;
Ik heb ook de DISTINCT
. terug toegevoegd naar je count()
die onderweg verloren zijn gegaan in uw zoekopdracht.