SQL中WHERE多条件用AND/OR连接,需注意AND优先级高于OR,混用时须加括号明确逻辑;IN可替代多个OR;字符串比较大小写敏感性因数据库而异;NULL需用IS NULL/IS NOT NULL显式判断;索引优化要求高选择性条件前置且避免字段函数操作。

WHERE 后面多个条件怎么写
直接用 AND 或 OR 连接就行,不需要额外括号——除非逻辑优先级有冲突。SQL 里 AND 优先级高于 OR,这点容易被忽略,一加错括号就查不到想要的数据。
比如想查“2023 年之后、状态为 active、且金额大于 100 的订单”,写成:
SELECT * FROM orders WHERE created_at > '2023-01-01' AND status = 'active' AND amount > 100;
如果混用 AND 和 OR,比如“状态是 active 或 pending,且金额大于 100”,就必须加括号明确范围:
SELECT * FROM orders WHERE (status = 'active' OR status = 'pending') AND amount > 100;
- 不加括号会变成:status = 'active' OR (status = 'pending' AND amount > 100),结果偏差很大
-
IN可替代多个=+OR,比如status IN ('active', 'pending') - 字符串比较注意大小写——MySQL 默认不区分,PostgreSQL 默认区分;不确定时显式用
ILIKE(PostgreSQL)或LOWER()
NULL 值在多条件中怎么处理
NULL 不等于任何值,包括它自己。所以 status != 'inactive' 会漏掉所有 status IS NULL 的行——这是最常踩的坑。
如果要包含 NULL,得单独判断:
SELECT * FROM users WHERE age > 18 AND (status != 'inactive' OR status IS NULL);
- 别写
status 'inactive',效果和!=一样,仍排除 NULL - 想排除 NULL 再比较?用
status IS NOT NULL AND status != 'inactive' - 某些场景可用
COALESCE(status, 'unknown') != 'inactive',但要注意索引失效风险
性能上多个 WHERE 条件要注意什么
不是条件越多越慢,而是“能走索引的条件”越靠前越好。数据库优化器通常从左到右评估 AND 条件,先过滤掉最多数据的列更高效。
- 把高选择性字段(如带索引的唯一 ID、时间范围)放在
AND左侧 - 避免在 WHERE 里对字段做函数操作,比如
YEAR(created_at) = 2023会让索引失效;改用created_at >= '2023-01-01' AND created_at - 用
EXPLAIN看执行计划,确认是否用了预期索引(尤其注意key和rows字段)
WHERE 多条件和 JOIN 条件容易混淆的地方
WHERE 是对最终结果过滤,ON 是控制关联逻辑。LEFT JOIN 中,把本该放 ON 的条件错写进 WHERE,会把 LEFT 变成 INNER。
例如想查“所有用户及其订单(哪怕没订单)”,但误写:
SELECT u.name, o.id FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE o.status = 'paid';
结果只返回有已支付订单的用户——因为 WHERE 在 JOIN 后执行,把 o.status IS NULL 的行全干掉了。
- 正确做法:把
o.status = 'paid'移到ON子句里 - 或者用子查询先筛订单,再 LEFT JOIN
- 记住口诀:过滤驱动表(主表)用
WHERE;过滤被驱动表(关联表)且允许 NULL,用ON
多个条件本身不难,难的是每一条都可能改变语义或性能边界。写完务必用小数据集验证结果行数,再看执行计划。

















