SQL查询求助:如何筛选符合特定标签组条件的产品?
搞定你的两个SQL查询需求
嘿,我来帮你梳理下这两个查询的正确写法,之前用INNER JOIN出问题是因为它会过滤掉没有关联标签/标签组的产品,咱们换成LEFT JOIN就能解决啦~
需求2:查询满足任一条件的产品
要么在tag_group为color的组下有tag为red的标签,要么完全没有tag_group为color的关联。
正确的SQL语句可以这样写:
SELECT DISTINCT product.name FROM product LEFT JOIN product_tag ON product.id = product_tag.product_id LEFT JOIN tag ON product_tag.tag_id = tag.id LEFT JOIN tag_group ON tag.tag_group_id = tag_group.id WHERE -- 情况1:匹配到color组的red标签 (tag_group.name = 'color' AND tag.name = 'red') -- 情况2:没有color组的关联(包括无标签/关联非color组的产品) OR (tag_group.name IS NOT NULL AND tag_group.name != 'color') OR (product_tag.product_id IS NULL);
或者用更直观的EXISTS子查询写法,逻辑更清晰:
SELECT DISTINCT product.name FROM product WHERE -- 情况1:存在color组的red标签 EXISTS ( SELECT 1 FROM product_tag pt JOIN tag t ON pt.tag_id = t.id JOIN tag_group tg ON t.tag_group_id = tg.id WHERE pt.product_id = product.id AND tg.name = 'color' AND t.name = 'red' ) -- 情况2:不存在任何color组的标签 OR NOT EXISTS ( SELECT 1 FROM product_tag pt JOIN tag t ON pt.tag_id = t.id JOIN tag_group tg ON t.tag_group_id = tg.id WHERE pt.product_id = product.id AND tg.name = 'color' );
为什么之前的写法不对?
你之前用INNER JOIN会直接排除所有没有标签/标签组关联的产品,而我们需要保留这些产品,所以LEFT JOIN是关键——它会返回左表(product)的所有记录,即使右表没有匹配项。
需求1:查询来自标签组或不属于任何标签组的产品
这个需求其实就是所有产品(因为产品要么属于某个标签组,要么完全没有标签),不过要注意去重,因为一个产品可能关联多个标签:
SELECT DISTINCT product.name FROM product LEFT JOIN product_tag ON product.id = product_tag.product_id LEFT JOIN tag ON product_tag.tag_id = tag.id LEFT JOIN tag_group ON tag.tag_group_id = tag_group.id;
如果你的意思是“属于至少一个标签组,或者完全没有任何标签(自然不属于任何标签组)”,上面的语句也能完美满足,LEFT JOIN会包含所有产品,DISTINCT会去掉重复的产品名。
内容的提问来源于stack exchange,提问作者Shaddow
相关产品推荐
相关产品推荐

