Postgres:使用ARRAY_AGG和HAVING(而不是WHERE)过滤结果

时间:2013-11-13 01:08:13

标签: sql postgresql

所以我的数据库包含项目列表:

items:  item.id | item.title

我还有第二个表格,它将许多标签与项目相关联:

tags:  tag.id | item.id

项目可能有多个与之关联的标记(例如5,20和25),因此标记表中的每个标记值都会有一行。

我希望能够确定特定标记是否与项目相关联,而不会丢失所有其他标记数据。例如,

SELECT items.id, items.title
FROM items
INNER JOIN tags ON (tag.tag_id=items.id)
WHERE tag.id =27

不起作用,因为它消除了包含其他标记值的行(如果tag.id为27,则它不能是特定行上的任何其他值)。

要解决这个问题,我想使用ARRAY_AGG将单个标签号码汇总到一个数组中,我可以(应该)轻松测试会员值。

SELECT items.id, items.title
FROM items
INNER JOIN tags ON (tag.tag_id=items.id)
GROUP BY items.id
HAVING ANY(ARRAY_AGG(tags.tag_id)=27)

(我看到this post about how you can't SELECT an AS-named column with ARRAY_AGG

但是上面的代码在HAVING子句的ANY部分产生语法错误。

思想?

1 个答案:

答案 0 :(得分:15)

事实证明Postgres的ANY keyword是双面的,不能对称使用。

因此工作代码是:

SELECT items.id, items.title, ARRAY_AGG(tags.tag_id)
FROM items
INNER JOIN tags ON (tag.tag_id=items.id)
GROUP BY items.id
HAVING 27 = ANY(ARRAY_AGG(tags.tag_id))