结论:AND 和 OR 混用必须加括号,因 AND 优先级高于 OR,否则逻辑错误;NOT 后接复合条件须括号包裹;IN 可简化多值 OR;ON/HAVING 等子句同样需括号;NULL 会使 AND 条件结果为 UNKNOWN 被过滤。

直接说结论:AND 和 OR 混用时,不加括号几乎必然出错——不是语法错,而是逻辑错,查出来的数据会悄悄漏掉或混入不该有的行。
WHERE里AND和OR混用,为什么结果总不对?
根本原因是运算符优先级:SQL 里 AND 永远比 OR 先执行,不管你怎么换行或缩进。解析器根本不看空格,只认规则。
比如这句:
WHERE status = 'active' OR role = 'admin' AND dept = 'tech'
实际等价于:
WHERE status = 'active' OR (role = 'admin' AND dept = 'tech')
而不是你脑内想的“活跃用户 或 管理员,并且部门是 tech”。
- 只要出现
AND和OR同时存在,无条件加括号 - 把语义上属于同一组的条件用
()明确圈起来,比如(status = 'active' OR status = 'pending') - 别指望靠缩进“暗示分组”,数据库不认这个
多个“或”条件怎么安全组合?
典型场景:查“订单状态是已发货或已完成,且支付方式是支付宝或微信”。这里有两个独立的“或”逻辑,必须各自包裹,再用 AND 连接。
正确写法:
WHERE (status = 'shipped' OR status = 'completed') AND (payment_method = 'alipay' OR payment_method = 'wechat')
更推荐用 IN 简化:
WHERE status IN ('shipped', 'completed') AND payment_method IN ('alipay', 'wechat')
-
IN比一长串OR更易读、更少拼写错误 - 但注意:
IN对NULL敏感,WHERE id IN (1, 2, NULL)中的NULL不生效,要单独写OR id IS NULL - 三个及以上等值判断,优先改用
IN
NOT 和复合条件一起用,最容易漏哪层括号?
NOT 只否定紧挨着它的下一个表达式,不是整条条件。写成 WHERE NOT a = 1 OR b = 2,实际是 (NOT a = 1) OR b = 2,不是你想的 NOT (a = 1 OR b = 2)。
- 只要
NOT后面跟着含AND/OR的表达式,就必须手动加括号包住整个被否定部分 - 否定“同时满足”,写
NOT (a = 1 AND b = 2) - 否定“任一满足”,写
NOT (a = 1 OR b = 2) - 别用
!=或替代NOT column = value处理复杂表达式,它对NULL和函数无效
JOIN 的 ON 子句和子查询里,括号还重要吗?
一样重要,而且更容易出错。因为 ON、子查询的 WHERE、甚至 HAVING 都遵循完全相同的优先级规则。
例如左连接中想保留所有用户,但只关联“状态有效且非测试账号”的订单:
LEFT JOIN orders ON users.id = orders.user_id AND (orders.status = 'valid' AND orders.is_test = 0)
-
AND后面的条件必须用括号包住,否则可能被当成主表过滤条件,破坏左连接语义 - 嵌套越深,括号层级越容易混乱,建议换行+缩进对齐,肉眼可读性比省字符重要得多
最常被忽略的不是语法,而是 NULL 行为:一旦条件里涉及可空字段(比如 updated_at、discount_rate),AND 会让整行变成 UNKNOWN 被过滤掉——这点在测试环境往往看不出来,上线后数据就莫名变少。











