and优先级恒高于or,不加括号会导致逻辑错位;必须用括号显式分组,如(a or b) and c,否则where a=1 or b=2 and c=3实际执行为a=1 or (b=2 and c=3)。

这不是设计选择,而是 SQL 标准强制规定的解析规则:AND 必须先于 OR 求值,和你“觉得该怎样”无关。
WHERE 里不加括号时,SQL 解析器怎么算?
数据库不会按你从左往右读的顺序执行条件,而是严格套用优先级:NOT > AND > OR。这意味着所有 AND 子句会先两两合并,再用 OR 把结果拼起来。
-
WHERE a = 1 OR b = 2 AND c = 3→ 实际等价于WHERE a = 1 OR (b = 2 AND c = 3) -
WHERE status = 'active' OR role = 'admin' AND dept = 'tech'→ 不是“活跃用户或管理员且部门是 tech”,而是“活跃用户,或者(管理员且部门是 tech)” - 哪怕你把
OR写在最前面,比如WHERE a = 1 OR b = 2 AND c = 3,AND依然先算
为什么不能靠记忆优先级来写 WHERE?
人脑记不住嵌套层级,尤其当条件里混入 IN、LIKE、函数或子查询时,AND/OR 的边界立刻模糊。更麻烦的是,错误不会报错,只会静默返回错数据。
-
WHERE name LIKE 'A%' OR name IN ('Bob', 'Charlie') AND age > 30→IN和LIKE同属第 7 级,但它们不参与跨操作符比较,实际仍是(name LIKE 'A%') OR (name IN (...) AND age > 30) -
WHERE NOT status = 'archived' OR status = 'draft'→NOT只作用于紧邻的status = 'archived',不是整个右边 - 只要出现两个以上逻辑运算符,就该默认加括号;哪怕只有一处
AND和一处OR,也值得加
哪些场景最容易栽在优先级上?
模糊搜索、软删除过滤、状态组合判断——这些地方一旦漏括号,deleted = 0 或 status IN ('active','pending') 就可能只约束部分分支,导致脏数据混入结果集。
- 典型翻车写法:
WHERE nomor_formulir LIKE '%mikha%' OR harga_pelita LIKE '%5%' AND deleted = 0→ 所有匹配'mikha'的行全被拉出来,不管deleted是 0 还是 1 - 正确写法必须是:
WHERE (nomor_formulir LIKE '%mikha%' OR harga_pelita LIKE '%5%') AND deleted = 0 - 如果还要兼容 NULL,得配合
COALESCE(nomor_formulir, '') LIKE '%mikha%',否则NULL LIKE返回 UNKNOWN,整行被过滤
真正卡住人的从来不是记不住 AND > OR,而是在敲完 WHERE 的瞬间,没停那半秒去核对括号是否真包住了你想表达的语义——线上问题八成死在这半秒犹豫上。










