0

我正在研究存储可标记项目的 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;
4

1 回答 1

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;
于 2015-06-18T17:52:41.367 回答