I want to be able to use unnest()
function in PostgreSQL in a complicated SQL query that has many JOIN
s. Here's the example query:
SELECT 9 as keyword_id, COUNT(DISTINCT mentions.id) as total, tags.parent_id as tag_id
FROM mentions
INNER JOIN taggings ON taggings.mention_id = mentions.id
INNER JOIN tags ON tags.id = taggings.tag_id
WHERE mentions.taglist && ARRAY[9] AND mentions.search_id = 3
GROUP BY tags.parent_id
I want to eliminate the taggings
table here, because my mentions
table has an integer array field named taglist that consists of all linked tag ids of mentions
.
I tried following:
SELECT 9 as keyword_id, COUNT(DISTINCT mentions.id) as total, tags.parent_id as tag_id
FROM mentions
INNER JOIN tags ON tags.id IN (SELECT unnest(taglist))
WHERE mentions.taglist && ARRAY[9] AND mentions.search_id = 3
GROUP BY tags.parent_id
This works but brings different results than the first query.
So what I want to do is to use the result of the SELECT unnest(taglist)
in a JOIN
query to compensate for the taggings
table.
How can I do that?
UPDATE: taglist
is the same set as the respective list of tag ids of mention.
Technically, your query might work like this (not entirely sure about the objective of this query):
However, it seems to me you are going in the wrong direction here. Normally one would remove the redundant array
taglist
and keep the normalized database schema. Then your original query should serve well, only shortened the syntax with aliases:Unravel the mystery
<rant>
The root cause for your "different results" is the unfortunate naming convention that some intellectually challenged ORMs impose on people.I am speaking of
as column name. Never use this anti-pattern in a database with more than one table. Right, that means basically any database. As soon as you join a bunch of tables (that's what you do in a database) you end up with a bunch of columns namedidid
. Utterly pointless.The ID column of a table named
tag
should betag_id
(unless there is another descriptive name). Neverid
.</rant>
Your query inadvertently counts
tags
instead ofmentions
:It should work this way:
I also added back the
DISTINCT
to yourcount()
that got lost along the way in your query.Something like this should work: