SQL WHERE:用 AND、OR 与 NULL 筛选行

SQL WHERE 子句用于按条件筛选表中的行。在 SQL 查询里,WHERE 子句只有在谓词计算结果为 TRUE 时才会保留该行,FALSE 和 NULL/UNKNOWN 都会被排除。这种三值逻辑是 WHERE 在处理 NULL 时最常见的异常行为来源。

SQL WHERE 行筛选示例

输出:

输出将显示在这里...

输出:

+--------+-----------+-------+
| name   | category  | price |
+--------+-----------+-------+
| 键盘   | 电子产品  | 49.99 |
| 鼠标   | 电子产品  | 25.0  |
+--------+-----------+-------+
2 row(s)

这个示例如何工作

  1. CREATE TABLEINSERT 创建了一个 products 表,四行数据分布在两个分类中。
  2. SQL 查询中的 WHERE 子句 category = '电子产品' AND price < 100AND 组合两个条件,两个条件都为 TRUE 时该行才会出现。
  3. “显示器”属于电子产品但价格是 299.00,因此被价格条件排除。“笔记本”未通过分类条件。最终只有“键盘”和“鼠标”同时满足两个谓词。

什么是 SQL WHERE 子句?

SQL WHERE 子句是逐行应用的布尔过滤器。数据库会对每一条候选行计算表达式,只保留结果为 TRUE 的行。返回 FALSE 或 NULL 的表达式都会被丢弃。WHERE 在 GROUP BY 和聚合函数之前执行,这也是它与 HAVING 的关键区别。

SQL WHERE 子句中的常见错误

错误:= 把列和 NULL 比较。

错误写法:

WHERE category = NULL

正确写法:

WHERE category IS NULL

原因:= NULL 的计算结果是 UNKNOWN,而 WHERE 会过滤掉 UNKNOWN 行。应使用 IS NULLIS NOT NULL

错误: 混用 ANDOR 时不加括号。

错误写法:

WHERE category = '办公用品' OR category = '电子产品' AND price < 50

正确写法:

WHERE (category = '办公用品' OR category = '电子产品') AND price < 50

原因:AND 的优先级高于 OR,要让逻辑与意图一致必须加括号。

WHERE 与 HAVING

WHEREHAVING
在分组前筛选单行在聚合后筛选分组
不能引用聚合函数可以引用 COUNTSUM 等聚合函数
减少进入 GROUP BY 的行数减少最终结果中的分组

规则:在聚合前排除行用 WHERE,在聚合后排除分组用 HAVING。尽早在 WHERE 里过滤,能减少聚合阶段的工作量。

性能注意事项

在已建立索引的列上使用 WHERE 谓词,可以把全表扫描变成索引查找。把列包在函数里(如 LOWER(name)DATE(created_at))会阻止优化器使用索引;应优先变换比较值而不是变换列。对于 AND 连接的条件,按谓词列顺序建立复合索引通常性能最好。OR 条件往往会触发多个索引扫描再合并,通常比同一索引上的 AND 更慢。

安全说明

构建 WHERE 条件时要使用参数化查询,绝不要把用户输入直接拼接进 SQL 字符串。动态列名必须先用严格的白名单校验。处理 IN (...) 列表时,生成占位符并逐个绑定值。执行 UPDATE 或 DELETE 前,先用完全相同的 WHERE 子句跑一条 SELECT 进行预览。

常见问题

SQL 中 WHERE 和 HAVING 的区别是什么?

WHERE 在 GROUP BY 前筛选行;HAVING 在聚合后筛选分组。WHERE 不能引用 COUNT()SUM() 这类聚合函数。一个查询可以同时使用两者:WHERE 先缩小输入行,再由 HAVING 缩小分组后的输出。

为什么 = NULL 在 WHERE 子句里不起作用?

SQL 使用三值逻辑:TRUE、FALSE、UNKNOWN。任何与 NULL 的比较都会得到 UNKNOWN,而 WHERE 会丢弃 UNKNOWN 行。判断 NULL 应使用 IS NULL。一些数据库也支持 IS NOT DISTINCT FROM,用于 NULL 安全的相等比较。

WHERE 子句中条件的书写顺序会影响性能吗?

SQL 标准不保证表达式计算顺序,多数优化器也会在内部重排谓词。条件按可读性最佳的顺序书写即可。真正影响性能的是列是否有索引以及每个谓词的选择性,而不是书写顺序。