SQL中多个WHERE条件用AND/OR连接,AND优先级高于OR,需用括号显式分组;IN替代多个OR更安全;NOT要紧贴目标;NULL值需用IS NULL判断;LIKE前导通配符影响索引;BETWEEN日期范围有歧义,推荐开闭区间。

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”。
- 用括号显式分组,避免靠记忆优先级:写成
WHERE (status = 'active' OR role = 'admin') AND dept = 'tech' -
IN能简化多个=并列:WHERE category IN ('A', 'B', 'C')比WHERE category = 'A' OR category = 'B' OR category = 'C'更安全、易读 -
NOT要紧贴目标表达式,NOT (a = 1 AND b > 5)比NOT a = 1 AND b > 5少出错
NULL值会让WHERE条件直接失效,别忘了IS NULL/IS NOT NULL
WHERE price > 100 不会匹配 price 是 NULL 的行,但很多人误以为它“跳过”或“默认不满足”——其实 NULL 和任何值比较(包括 =、>、!=)结果都是 UNKNOWN,而 WHERE 只认 TRUE。
- 判断空值必须用
IS NULL或IS NOT NULL,不能写= NULL - 混合条件时,
AND链中只要一个UNKNOWN,整条就不是TRUE:例如WHERE name = 'Alice' AND age > 30,若某行age是NULL,这行一定被过滤掉 - 需要包含空值时,显式写出分支:
WHERE (status = 'pending' OR status IS NULL)
字符串模糊匹配加WHERE,LIKE和性能陷阱得一起看
LIKE 看似简单,但通配符位置直接影响索引是否生效。前导百分号(如 LIKE '%word')基本等于全表扫描。
- 尽量把通配符放在右边:
LIKE 'prefix%'才可能走索引(前提是字段有索引且优化器选用了) - 区分大小写取决于数据库配置;PostgreSQL 默认区分,MySQL 通常不区分,需要时用
ILIKE(PG)或COLLATE utf8mb4_0900_as_cs - 模糊匹配含特殊字符(
%、_)要转义:LIKE '100\%' ESCAPE '\',否则字面意思的百分号会被当通配符
日期范围过滤常踩的坑:BETWEEN不够准,TIMESTAMP时区容易漏
BETWEEN '2024-01-01' AND '2024-01-31' 看似覆盖整月,但如果字段是 TIMESTAMP 类型,它实际只查到 '2024-01-31 00:00:00',当天其余时间全丢了。
- 推荐用开闭区间:
WHERE created_at >= '2024-01-01' AND created_at ,语义清晰、无歧义、能用索引 - 涉及跨时区数据,确认字段存的是 UTC 还是本地时间;
WHERE created_at >= NOW() - INTERVAL '7 days'在 PostgreSQL 中依赖会话时区,可能查偏 - 字符串转日期别依赖隐式转换:
WHERE date_str >= '2024-01-01'如果date_str是文本类型,可能触发全表转换,应先用TO_DATE()或STR_TO_DATE()显式转换
实际写多条件 WHERE 时,最麻烦的往往不是语法,而是每个字段的空值策略、时区上下文、索引可用性——这些不检查清楚,加再多括号也救不回慢查询。










