MySQL 零基础教程

MySQL WHERE 子句

默认情况下,SELECT 语句会检索表中的所有行。但在实际应用中,你极少需要获取表中的每一条记录。WHERE 子句就像一个守门员,在将行返回到结果集之前,根据特定条件对它们进行过滤。它通常位于你的 FROM 子句和任何排序或限制逻辑之间。

1. 过滤查询的结构

当你添加 WHERE 子句时,数据库会对目标表中的每一行评估该条件。如果条件评估为 TRUE(真),则该行将包含在输出中;如果为 FALSE(假)或 UNKNOWN(未知,常见于 NULL 值),则该行将被丢弃。

SELECT name, population 
FROM city 
WHERE population > 1000000;

这个查询告诉 MySQL 去查找 city(城市)表,检查每一行的 population(人口)列,并且只返回那些人口值严格大于一百万的行。

2. 比较运算符

MySQL 提供了标准的运算符来定义这些过滤条件。能否有效地使用它们,取决于运算符与列的数据类型是否匹配。

运算符含义示例用法
=等于WHERE countrycode = 'USA'
<>!=不等于WHERE language != 'English'
<小于WHERE gnp < 5000
<=小于或等于WHERE surfacearea <= 1000
>大于WHERE population > 5000000
>=大于或等于WHERE year >= 2000

3. 处理字符串和日期

与数字比较不同,字符串在查询时必须用单引号括起来。在默认的标准字符集排序规则下,MySQL 通常是不区分大小写的,因此 'USA''usa' 通常会产生相同的结果。

-- 查询 district(行政区)为 'California'(加利福尼亚)的行
SELECT * FROM city 
WHERE district = 'California';

-- 从特定日期起查询记录(注:以官方标识 T 为例)
SELECT * FROM countrylanguage 
WHERE isofficial = 'T';

4. 数据库如何处理过滤

在数据库引擎中可视化操作的顺序非常重要。WHERE 子句在查询的生命周期中处理得非常早。

  1. FROM 表:首先确定数据来源。
  2. 应用 WHERE 过滤:对每一行进行条件判断。
    • 条件满足 -> 选择列 -> 加入 最终结果集
    • 条件未满足 -> 丢弃行

5. 处理边界情况和数据类型

初学者常见的一个陷阱是假设所有数据类型都像数字一样表现。

  • 精度 (Precision): 当在 WHERE 子句中使用浮点数时,要谨慎使用 = 运算符。由于计算机底层存储浮点运算的方式,一个值可能是 10.000000001 而不是严格的 10。使用范围区间(例如 >= 10 AND <= 10.00001)可以获得更好的查询稳定性。
  • 日期格式 (Date Formats): MySQL 期望的默认日期格式是 YYYY-MM-DD(年-月-日)。如果你的字符串是 MM-DD-YYYY,查询要么无法返回结果,要么会直接报错,因为它无法将该字符串正确转换为有效的日期对象来进行比较。
  • 隐式转换 (Implicit Conversion): 如果你将字符串列与数字进行比较(例如 WHERE name = 123),MySQL 将尝试将字符串转换为数字。这非常危险,并可能导致严重的性能问题,因为数据库引擎往往不得不放弃使用索引来执行这种全表转换。请始终确保你的比较值与列的数据类型相匹配。