逻辑组合是什么
AND / OR / NOT 把多个布尔条件组合成一个判定。优先级是固定的:NOT 最高,其次 AND,最后 OR,所以 a AND b OR c 等价于 (a AND b) OR c。SQL 也不承诺短路求值,优化器可以重排条件、提前计算子表达式,因此不能靠书写顺序去“保护”可能报错的表达式。
基本信息
| 优先级 | NOT > AND > OR |
|---|---|
| 括号 | 多条件组合一律显式加括号,语义与可读性都更好 |
| 求值顺序 | 标准不保证短路,MySQL 与 PostgreSQL 都可能重排条件 |
| 三值逻辑 | 结果为 TRUE / FALSE / UNKNOWN 三种,NULL 参与运算得 UNKNOWN |
| WHERE 语义 | 只有结果为 TRUE 的行被保留,UNKNOWN 等同不匹配 |
优先级与括号
优先级与括号
SELECT * FROM t
WHERE a = 1 AND b = 2 OR c = 3; -- 等价于 (a=1 AND b=2) OR c=3
SELECT * FROM t
WHERE (a = 1 OR b = 2) AND c = 3; -- 显式括号:只保留同时满足 c=3 的行
SELECT * FROM t
WHERE NOT (status = 1 OR status = 2); -- NOT 作用于整个括号,不是只作用于第一项
SELECT * FROM t
WHERE (a = 1 OR b = 2) AND c = 3; -- 评审时先看括号是否表达业务原意三值逻辑演示
三值逻辑演示
SELECT 0 AND NULL; -- 0:有一侧为假,结果必假
SELECT 1 AND NULL; -- NULL:另一侧未知
SELECT 0 OR NULL; -- NULL:另一侧未知
SELECT 1 OR NULL; -- 1:有一侧为真,结果必真
SELECT NOT NULL; -- NULL:取反后仍是未知
SELECT NULL AND NULL; -- NULL三值逻辑真值表
| 表达式 | 结果 | 说明 |
|---|---|---|
| FALSE AND NULL | FALSE | 有一侧为假即确定 |
| TRUE AND NULL | UNKNOWN | 无法确定为真 |
| TRUE OR NULL | TRUE | 有一侧为真即确定 |
| FALSE OR NULL | UNKNOWN | 取决于未知的一侧 |
| NOT NULL | UNKNOWN | 取反不改变未知 |
| WHERE 结果 UNKNOWN | 过滤掉该行 | 与 FALSE 的处理相同 |
典型使用场景
- 叠加多个筛选维度:状态、时间范围、渠道等条件组合
- 同类字段枚举匹配,如 status IN (1,2) 或等价的 OR 写法
- 用 NOT 排除某类数据,注意 NULL 行不会因取反而被保留
- 在 JOIN 的 ON 里组合多列关联条件,避免挪到 WHERE 后改变外连接语义
- 拼接动态查询条件时给整段条件补括号,防止优先级被静默改写
想保留 NULL 行要显式写出来:NOT (col = 1) 会连 NULL 行一起排除,写成 col IS NULL OR col <> 1 才符合“不是 1 的都算”的直觉。
不要依赖短路顺序。优化器可能先执行本应被前面的条件挡住的子表达式,除法、类型转换、函数解析这类可能报错的操作要用 CASE 显式判断,而不是靠 AND 的书写顺序。