MySQL同一列多条件查询:如何实现指定逻辑的查询?
解决多属性条件下的model_id筛选问题
我完全懂你的困扰——你想要找出同时满足多组属性规则的model_id,但原来的SQL写法没法得到预期结果,核心原因是:你的model_attributes表是每行对应一个属性,同一条记录不可能同时有attributes_id=2和attributes_id=4,所以直接用AND连接这些条件根本找不到匹配的行。
下面给你两种经过验证的可行方案,都能帮你拿到model_id=8、9的结果:
方案1:GROUP BY + HAVING(最通用的做法)
这种方法通过分组统计每个model_id满足的条件数量,确保它覆盖所有你需要的属性组:
SELECT model_id FROM model_attributes WHERE -- 先过滤出所有可能符合条件的记录,减少后续计算量 (attributes_id = 2 AND attributes_value = '32mb') OR (attributes_id = 4 AND attributes_value IN ('5.00 inch', '6.00 inch')) OR (attributes_id = 5 AND attributes_value IN ('here', 'asfdsdf')) GROUP BY model_id HAVING -- 确保该model_id拥有attributes_id=2且值为32mb的属性 SUM(CASE WHEN attributes_id=2 AND attributes_value='32mb' THEN 1 ELSE 0 END) >= 1 -- 确保拥有attributes_id=4且值是指定两个中的一个 AND SUM(CASE WHEN attributes_id=4 AND attributes_value IN ('5.00 inch', '6.00 inch') THEN 1 ELSE 0 END) >=1 -- 确保拥有attributes_id=5且值是指定两个中的一个 AND SUM(CASE WHEN attributes_id=5 AND attributes_value IN ('here', 'asfdsdf') THEN 1 ELSE 0 END) >=1;
逻辑说明:
- 每个
CASE语句会检查当前记录是否满足对应属性组的要求,满足就记1,不满足记0 SUM()会统计每个model_id在该属性组下的合格记录数HAVING子句要求每个属性组的合格数至少为1,也就是这个model_id必须同时满足所有属性规则
方案2:多表JOIN(直观易懂的写法)
把同一个表按不同属性条件多次连接,只有当model_id在所有连接中都有匹配时,才会被选中:
SELECT DISTINCT ma2.model_id FROM model_attributes ma2 -- 连接满足attributes_id=4条件的记录 JOIN model_attributes ma4 ON ma2.model_id = ma4.model_id AND ma4.attributes_id =4 AND ma4.attributes_value IN ('5.00 inch', '6.00 inch') -- 连接满足attributes_id=5条件的记录 JOIN model_attributes ma5 ON ma2.model_id = ma5.model_id AND ma5.attributes_id =5 AND ma5.attributes_value IN ('here', 'asfdsdf') -- 主表筛选attributes_id=2的条件 WHERE ma2.attributes_id=2 AND ma2.attributes_value='32mb';
逻辑说明:
- 每个
JOIN相当于给model_id增加一层属性校验 - 只有当某个
model_id同时存在于ma2、ma4、ma5三个结果集中时,才会被最终选中 DISTINCT用来避免重复结果(如果同一个model_id有重复属性记录的话)
为什么原来的写法无效?
你原来的SQL要求同一条记录同时满足attributes_id=2、attributes_id=4、attributes_id=5,但你的表结构里每行只能对应一个attributes_id,自然找不到匹配的记录。这两种方案都是把同一个model_id的不同属性记录整合起来判断,完美匹配你的需求。
内容的提问来源于stack exchange,提问作者Rabin Lama Dong
相关产品推荐
相关产品推荐

