SQL使用WHERE NOT、AND与OR组合时过滤逻辑不符合预期怎么办?
问题根因
- SQL 逻辑运算符存在固定优先级:
AND优先级高于OR,未按预期加括号时,条件会自动按优先级拆分执行 - 原查询的WHERE子句实际执行逻辑等价于:
因此(NOT gsued.status = 'Actioned' AND gsuo.user_id = '62') OR (gsuo.user_id = '14')gsuo.user_id = '14'的分支完全不受NOT gsued.status = 'Actioned'的约束,和预期过滤逻辑不符。 - 自行加括号仍无效的常见原因:括号未调整优先级逻辑,比如直接把整段WHERE条件套一层括号,或者括号位置放错,没有把两个OR匹配的用户条件作为整体和NOT条件做AND关联。
修正方案
如果你的预期是两个用户的所有查询结果都要排除gsued.status = 'Actioned'的记录,即所有结果需同时满足:
- 事件数据
gsued.status不等于Actioned - 关联用户ID属于
62或14
对应可选择以下两种写法:
写法1(更简洁的IN匹配)
SELECT gsu.*, gsuo.*, gsob.*, gsued.* FROM gs_users gsu INNER JOIN gs_user_objects gsuo ON gsu.id = gsuo.user_id INNER JOIN gs_objects gsob ON gsuo.imei = gsob.imei INNER JOIN gs_user_events_data gsued ON gsuo.imei = gsued.imei WHERE gsued.status != 'Actioned' AND gsuo.user_id IN ('62', '14') GROUP BY gsued.dt_tracker ORDER BY gsued.dt_tracker
写法2(保留OR逻辑的正确括号用法)
SELECT gsu.*, gsuo.*, gsob.*, gsued.* FROM gs_users gsu INNER JOIN gs_user_objects gsuo ON gsu.id = gsuo.user_id INNER JOIN gs_objects gsob ON gsuo.imei = gsob.imei INNER JOIN gs_user_events_data gsued ON gsuo.imei = gsued.imei WHERE gsued.status != 'Actioned' AND (gsuo.user_id = '62' OR gsuo.user_id = '14') GROUP BY gsued.dt_tracker ORDER BY gsued.dt_tracker
额外注意点
- 原查询SELECT了多表的全量字段,但仅按
gsued.dt_tracker分组,在开启ONLY_FULL_GROUP_BY的MySQL模式下会直接抛出语法错误,需要根据实际聚合需求补充分组字段,或调整聚合逻辑。 - 用
!=/<>替代NOT 字段 = 值的写法更直观,可降低括号嵌套写错的概率。
内容的提问来源于stack exchange,提问作者eTrack
相关产品推荐
相关产品推荐

