where子句是sql查询的过滤主干,必须紧随from或join之后,字符串值需单引号、null须用is null判断、and/or逻辑需括号明确优先级。

WHERE 子句不是可选装饰,而是 SQL 查询的过滤主干——漏写、写错位置或误用逻辑运算符,直接导致查到空结果或全表扫描。
WHERE 必须紧跟在 FROM 或 JOIN 之后
常见错误是把 WHERE 放在 GROUP BY 或 ORDER BY 后面,或者插在 SELECT 和 FROM 中间。SQL 解析器会直接报错:ERROR: syntax error at or near "WHERE"。
-
SELECT name, age FROM users WHERE age > 18✅ 正确顺序 -
SELECT name FROM users ORDER BY name WHERE age > 18❌ 报错:WHERE 不能在 ORDER BY 后 -
SELECT name WHERE age > 18 FROM users❌ 报错:WHERE 不能在 SELECT 和 FROM 之间
字符串值必须用单引号包裹,数字不用
这是新手最常踩的坑:'admin' 是字符串,admin 是列名,123 是数字——混用会导致意外匹配或类型转换错误。
-
WHERE status = 'active'✅ 字符串加单引号 -
WHERE id = 1001✅ 数字不加引号 -
WHERE email = 'user@domain.com'✅ 邮箱含 @ 和 .,仍属字符串,必须加引号 -
WHERE created_at > '2024-01-01'✅ 日期字符串也要引号
NULL 值不能用 = 判断,得用 IS NULL
= NULL 永远返回 false,因为 SQL 中 NULL 表示“未知”,任何与 NULL 的等值比较结果都是 unknown(不等于 true)。写成 WHERE column = NULL 看似合理,实际查不到任何行。
-
WHERE phone IS NULL✅ 正确判断空值 -
WHERE phone IS NOT NULL✅ 正确排除空值 -
WHERE phone = NULL❌ 永远不成立,等价于没加条件 -
WHERE phone != '123'会自动过滤掉phone IS NULL的行,注意隐式排除
AND / OR 优先级容易出错,多用括号明确逻辑
AND 优先级高于 OR,不加括号时 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。
- 想查“状态是 active 或 pending,且类型是 user”:用
WHERE (status = 'active' OR status = 'pending') AND type = 'user' - 混合使用时,哪怕看起来简单,也建议统一加括号,避免后期加条件后逻辑崩坏
- 数据库对括号嵌套深度一般无硬限制,但超过三层建议拆成子查询或 CTE,提升可读性
WHERE 的边界很窄——它只管行级过滤,不碰聚合、不改排序、不处理重复。写完记得确认:条件是否覆盖了所有可能取值(比如枚举字段漏了新状态),是否无意中把 NOT 写反,以及有没有在高并发更新场景下忽略幻读风险。











