如何查询同时关联标签3/4与6的objects表条目?
解决同时关联多个标签的筛选问题
你猜的没错,那条注释掉的条件之所以查不出结果,核心原因就是单条objects_tags记录里的id_tag不可能同时满足「是3或4」和「是6」——毕竟每条关联记录只能对应一个标签,同一行的字段值总不能“分身”同时匹配两个互斥的条件呀。
要筛选出既关联了标签3/4、又关联了标签6的objects条目,这里给你两种常用且靠谱的解决方案:
方法1:GROUP BY + HAVING(推荐,标签多的时候更灵活)
这种思路是先把所有和目标标签相关的关联记录捞出来,再通过分组统计,确保每个object同时满足两个标签条件:
SELECT objects.id FROM objects JOIN objects_tags ON objects.id = objects_tags.id_object WHERE objects_tags.id_tag IN (3,4,6) -- 先缩小范围,只保留和目标标签相关的记录 GROUP BY objects.id HAVING -- 必须包含标签6 SUM(CASE WHEN objects_tags.id_tag = 6 THEN 1 ELSE 0 END) > 0 -- 必须包含3或4中的至少一个 AND SUM(CASE WHEN objects_tags.id_tag IN (3,4) THEN 1 ELSE 0 END) > 0;
如果你的业务里不会出现同一个object重复关联同一个标签的情况,上面的写法完全够用;如果有重复关联的场景,把SUM换成COUNT(DISTINCT ...)或者在HAVING里加个COUNT(DISTINCT objects_tags.id_tag) >= 2来确保是不同标签的匹配。
方法2:多次JOIN关联表(直观易懂,小数据量友好)
这种思路是通过多次关联objects_tags表,分别匹配不同的标签要求,相当于给object做两次“标签校验”:
SELECT DISTINCT objects.id FROM objects -- 先匹配关联了3或4的记录 JOIN objects_tags ot1 ON objects.id = ot1.id_object AND ot1.id_tag IN (3,4) -- 再匹配同时关联了6的记录 JOIN objects_tags ot2 ON objects.id = ot2.id_object AND ot2.id_tag = 6;
这里加DISTINCT是为了避免同一个object因为多次匹配而重复出现在结果里。
两种方法各有优劣:GROUP BY的方式在需要匹配更多标签时扩展性更好,而多次JOIN的写法更直观,新手也更容易理解。
内容的提问来源于stack exchange,提问作者if-trubite
相关产品推荐
相关产品推荐

