括号是SQL逻辑运算的必需指令,AND优先级高于OR,NOT仅作用于紧随其后的单个条件,NULL参与运算结果为UNKNOWN,必须显式处理。

AND 和 OR 混用时,不加括号几乎必然出错
SQL 里 AND 优先级高于 OR,但人脑很难在嵌套中实时还原运算顺序。比如写 WHERE status = 'active' OR role = 'admin' AND level > 5,实际等价于 WHERE status = 'active' OR (role = 'admin' AND level > 5),而不是你直觉想表达的“活跃用户或管理员且等级大于5”。
实操建议:
- 只要
OR和AND出现在同一层(没被外层括号包裹),就强制用括号分组 - 把每个逻辑单元单独括起来,例如
(status = 'active')、(role = 'admin' AND level > 5),再用OR连接 - 避免写成
A OR B AND C OR D这类裸链式结构,哪怕看起来“简单”
NOT 与 AND/OR 共存时,括号不是可选,是必须
NOT 虽然优先级最高,但它只作用于紧随其后的单个条件或子表达式。一旦后面跟着 AND 或 OR,不加括号就会让语义失控。例如 NOT status = 'draft' AND amount > 1000 实际执行为 (NOT status = 'draft') AND amount > 1000,这没问题;但若本意是“排除(草稿且金额大于1000)的记录”,就得写成 NOT (status = 'draft' AND amount > 1000)。
常见错误现象:
- 用
NOT a = 1 AND b = 2试图排除同时满足两个条件的行 → 实际排除的是a ≠ 1且b = 2的行 - 在
IN或BETWEEN前直接加NOT,如NOT age BETWEEN 18 AND 25→ 正确,但NOT age IN (18, 19)更安全,因为BETWEEN对 NULL 不敏感 - 忽略
NOT无法穿透括号:写NOT (a = 1 OR b = 2)等价于a ≠ 1 AND b ≠ 2,不是NOT a = 1 OR NOT b = 2
用 CASE 配合布尔逻辑替代模糊的 WHERE 嵌套
当判断逻辑涉及状态转换、阈值分段或依赖字段组合时,硬塞进 WHERE 容易失控。比如“VIP 用户放宽登录时效,普通用户严格限制”,用纯 AND/OR/NOT 写会冗长且难维护。
实操建议:
- 把分支逻辑抽到
CASE表达式里,返回布尔值或标志位,再用于过滤:WHERE CASE WHEN user_type = 'VIP' THEN last_login > DATE_SUB(NOW(), INTERVAL 30 DAY) ELSE last_login > DATE_SUB(NOW(), INTERVAL 7 DAY) END -
CASE支持任意布尔表达式,比单纯拼AND/OR更贴近业务描述,也更容易加注释 - 注意
CASE在WHERE中不能返回NULL——如果分支没覆盖全,补上ELSE FALSE,否则整行可能被意外过滤
空值(NULL)会让所有逻辑运算结果变成 UNKNOWN
任何字段参与 =、!=、AND、OR、NOT 时,只要其中一端是 NULL,整个条件结果就是 UNKNOWN,而 WHERE 只保留 TRUE 行。这意味着 status != 'draft' 不会匹配 status IS NULL 的记录,哪怕它确实“不是草稿”。
关键处理点:
- 显式判断空值:用
IS NULL或IS NOT NULL,不要用= NULL或!= NULL - 在复杂条件中提前处理空值,例如用
COALESCE(status, 'unknown')统一兜底,再参与比较 - 用
NOT (status = 'draft')时,记得它不包含status IS NULL的行;真要排除草稿和空值,得写NOT (status = 'draft' OR status IS NULL)
NOT 的作用域,或者某处 NULL 悄悄把整条判断变 UNKNOWN。

















