İlk*_*anç 5 sql postgresql join naming-conventions unnest
我希望能够unnest()在一个复杂的SQL查询中使用PostgreSQL中的函数,该查询有很多JOINs.这是示例查询:
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
Run Code Online (Sandbox Code Playgroud)
我想在taggings这里删除表,因为我的mentions表有一个名为taglist的整数数组字段,它包含所有链接的标记ID .mentions
我试过以下:
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
Run Code Online (Sandbox Code Playgroud)
这有效,但带来的结果与第一个查询不同.
因此,我想要做的是使用的结果SELECT unnest(taglist)的JOIN查询,以补偿taggings表.
我怎样才能做到这一点?
更新: taglist与提及的标签ID的相应列表相同.
从技术上讲,您的查询可能会像这样工作(不完全确定此查询的目标):
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;
Run Code Online (Sandbox Code Playgroud)
但是,在我看来,你在这里走错了方向.通常会删除冗余阵列taglist并保留规范化的数据库架构.然后你的原始查询应该很好用,只用别名缩短语法:
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;
Run Code Online (Sandbox Code Playgroud)
<rant>
你的"不同结果"的根本原因是一些不幸的命名惯例,一些智力挑战的ORM强加于人.
我说的是列名.切勿在具有多个表的数据库中使用此反模式.对,这基本上意味着任何数据库.一旦你加入了一堆表(这就是你在数据库中所做的那样),你就会得到一堆名为的列idid.毫无意义.
名为的表的ID列tag应该是tag_id(除非有另一个描述性名称).从不id.
</rant>
您的查询无意中计数tags而不是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;
Run Code Online (Sandbox Code Playgroud)
它应该这样工作:
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;Run Code Online (Sandbox Code Playgroud)
我还在你的查询中添加了DISTINCT你count()丢失的信息.