Postgres查询列出与某些标签匹配的项目的所有folksonomy标签

时间:2015-06-17 12:49:06

标签: postgresql left-join folksonomy

我正在处理一个存储可标记项目的Postgres数据库;它使用典型的限制(带有item_id的项的表,带有tag_id和tag_name的标签的表,给定项具有给定标记的每个实例的表)。我已经组装了这个几乎完成我想要的查询,检索与至少一个所选标签匹配的项目并显示有关该项目的所有信息:

SELECT items.item_id, items.item_name, items.item_description,
    ARRAY_AGG(tags.tag_name) AS tag_name_list
FROM items
LEFT JOIN item_tags ON items.item_id = item_tags.item_id
LEFT JOIN tags ON tags.tag_id = item_tags.tag_id
WHERE tags.tag_name  IN ('one','two') 
GROUP BY items.item_id;

问题是列出项目标签的部分只列出匹配的部分,而不是所有部分。 (例如,如果某些内容包含一个,两个和三个标记,则此特定查询将建议它只有一个和两个。)

我想我可以使用嵌套的SELECT语句进行此操作,但这感觉更正确,而且我还没有想出如何以这种方式执行此操作。

编辑:根据建议,我已将其修改为此但我得到了完全相同的结果。

SELECT items.item_id, items.item_name, items.item_description,
    ARRAY_AGG(tags.tag_name) AS tag_name_list
FROM items
LEFT JOIN item_tags ON items.item_id = item_tags.item_id
LEFT JOIN tags ON tags.tag_id = item_tags.tag_id
WHERE EXISTS (SELECT * FROM tags
    WHERE tags.tag_name IN ('two','three')
    AND tags.tag_id = item_tags.tag_id
) 
GROUP BY items.item_id;

编辑2:所以我选择了子查询方法:

SELECT items.item_id, items.item_name, items.item_description,
    ARRAY_AGG(tag_name) AS tag_name_list
FROM item_tags, tags, items

WHERE item_tags.item_id IN
(
    SELECT DISTINCT item_id FROM item_tags WHERE tag_id IN
    (
        SELECT tag_id FROM tags WHERE tag_name  IN ('one','two')
    )
)
AND tags.tag_id = item_tags.tag_id
AND items.item_id = item_tags.item_id

GROUP BY items.item_id;

1 个答案:

答案 0 :(得分:0)

SELECT i.item_id, i.item_name, i.item_description,
    ARRAY_AGG(t.tag_name) AS tag_name_list
FROM items i
JOIN tags t ON EXISTS (
        SELECT * FROM item_tags it
        WHERE i.item_id = it.item_id
        AND t.tag_id = it.tag_id
        )
WHERE EXISTS (
        SELECT * FROM item_tags xit
        JOIN tags t ON t.tag_id = xit.tag_id
        WHERE xit.item_id = i.item_id
        AND t.tag_name  IN ('one','two')
        )
GROUP BY i.item_id;