SQL中AND优先级高于OR,WHERE a=1 OR b=2 AND c=3等价于a=1 OR (b=2 AND c=3),非(a=1 OR b=2) AND c=3;混用时必须加括号明确逻辑分组,否则易导致漏数据或误过滤。

不加括号的 AND 和 OR 混用,SQL 会按固定优先级解析,不是你读着顺眼那样算的——结果常漏数据、误过滤,而且所有主流数据库(MySQL/PostgreSQL/SQL Server)都这么干,没法绕开。
WHERE a=1 OR b=2 AND c=3 实际等于什么
它等价于 WHERE a=1 OR (b=2 AND c=3),不是 (a=1 OR b=2) AND c=3。因为 AND 优先级明确高于 OR,和 NOT > AND > OR 这个顺序一致。
- 写
city = '北京' OR city = '上海' AND gender = '女',查出来的是「所有北京用户 + 上海女性用户」,不是「北京女性或上海女性」 - 用
EXPLAIN看执行计划,看不出括号是否合理——它只管怎么快,不管逻辑对不对 - 靠缩进、换行、空格“暗示分组”完全无效;数据库不认格式,只认括号
什么时候必须加括号
只要条件不是纯线性(比如全是 AND 或全是 OR),就该加。尤其以下场景极易翻车:
- 业务逻辑天然有分组:比如「(北京男用户) 或 (上海VIP用户)」→ 必须写成
(city = '北京' AND gender = '男') OR (city = '上海' AND is_vip = true) - 混入
NOT:写NOT a = 1 OR b = 2实际是(NOT a = 1) OR b = 2,想否定整个 OR 组合就得写NOT (a = 1 OR b = 2) - 子查询参与复合条件时:
WHERE id IN (SELECT ...) AND status = 'active' OR type = 'admin',没括号就会先算子查询关联部分再和OR拼,容易漏行
括号太多怎么办
三层以上嵌套,比如 ((a AND b) OR (c AND (d OR e))),人脑已经难校验。这时候别硬堆括号:
- 拆成 CTE:用
WITH active_users AS (...), vip_shanghai AS (...) SELECT ... FROM active_users UNION SELECT ... FROM vip_shanghai - 或者提前提取中间结果到临时表,让每层逻辑独立可测
- 用 SQL 格式化工具(如 sqlformat.org)粘贴语句,看它是否自动补了你漏的括号——如果补了,说明你原来写的真有歧义
- CI 流程里加
sqlfluff,规则L017专抓AND/OR混用缺括号的问题
括号不是语法装饰,是你和数据库之间关于“哪部分先算、哪部分一起判”的书面约定。漏一个,逻辑就可能偏移;多一层嵌套,后续人维护时踩坑概率就指数上升。










