前面我们已经学习了 SELECT 查询语句的基础用法,掌握了查询全部字段、选取指定列,以及为查询字段设置别名来美化结果集的操作。
但很多实际业务场景中,我们并不需要表中全部的数据,只希望取出满足条件的部分记录,这时就可以使用 WHERE 子句对查询结果做数据过滤。
下面就来详细讲解 WHERE 子句的使用:
比较运算符用于对两个值做对比,返回真假(true/false),数据库只把条件为真(true)的数据行保留下来。
注意:
MySQL 中 = 代表相等判断,不要使用==。
MySQL 中空值判断是 IS NULL,切忌使用 = NULL。
当需要多个条件同时限制时,可以搭配 AND、OR、NOT 逻辑运算符拼接多个比较条件。
支持的比较运算如下表:
| 运算符 | 说明 | 示例 |
|---|---|---|
= | 等于(MySQL 中等于用一个 =,不是 ==) | where user_age = 20 |
<>/ != | 不等于 | where user_age <> 30 |
> | 大于 | where user_age > 18 |
< | 小于 | where user_age < 60 |
>= | 大于等于 | where user_age >= 18 |
<= | 小于等于 | where user_age <= 50 |
示例:
(1)等于:查询用户ID为1的记录
mysql> select * from users where user_id=1;
+---------+-----------+----------+----------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+-----------+----------+----------------------+-------------+---------------------+
| 1 | zhang_san | 23 | zhangsan@example.com | 13800138001 | 2026-07-29 13:55:25 |
+---------+-----------+----------+----------------------+-------------+---------------------+
1 row in set (0.00 sec)(2)不等于:查询用户ID不为1的记录
mysql> select * from users where user_id!=1;
+---------+-------------+----------+---------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+-------------+----------+---------------------+-------------+---------------------+
| 2 | li_si | 28 | lisi@example.com | 13800138002 | 2026-07-29 13:55:25 |
| 3 | wang_wu | 35 | wangwu@example.com | 13800138003 | 2026-07-29 13:55:25 |
| 4 | zhao_liu | 19 | zhaoliu@example.com | NULL | 2026-07-29 13:55:25 |
| 5 | qian_qi | 42 | qianqi@example.com | 13800138005 | 2026-07-29 13:55:25 |
| 6 | sun_ba | 26 | sunba@example.com | 13800138006 | 2026-07-29 13:55:25 |
| 7 | zhou_jiu | 31 | zhoujiu@example.com | NULL | 2026-07-29 13:55:25 |
| 8 | wu_shi | 50 | wushi@example.com | 13800138008 | 2026-07-29 13:55:25 |
| 9 | zheng_shiyi | 22 | zheng11@example.com | 13800138009 | 2026-07-29 13:55:25 |
| 10 | chen_shier | 38 | chen12@example.com | 13800138010 | 2026-07-29 13:55:25 |
+---------+-------------+----------+---------------------+-------------+---------------------+
9 rows in set (0.00 sec)
-- 效果相同
mysql> select * from users where user_id<>1;
+---------+-------------+----------+---------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+-------------+----------+---------------------+-------------+---------------------+
| 2 | li_si | 28 | lisi@example.com | 13800138002 | 2026-07-29 13:55:25 |
| 3 | wang_wu | 35 | wangwu@example.com | 13800138003 | 2026-07-29 13:55:25 |
| 4 | zhao_liu | 19 | zhaoliu@example.com | NULL | 2026-07-29 13:55:25 |
| 5 | qian_qi | 42 | qianqi@example.com | 13800138005 | 2026-07-29 13:55:25 |
| 6 | sun_ba | 26 | sunba@example.com | 13800138006 | 2026-07-29 13:55:25 |
| 7 | zhou_jiu | 31 | zhoujiu@example.com | NULL | 2026-07-29 13:55:25 |
| 8 | wu_shi | 50 | wushi@example.com | 13800138008 | 2026-07-29 13:55:25 |
| 9 | zheng_shiyi | 22 | zheng11@example.com | 13800138009 | 2026-07-29 13:55:25 |
| 10 | chen_shier | 38 | chen12@example.com | 13800138010 | 2026-07-29 13:55:25 |
+---------+-------------+----------+---------------------+-------------+---------------------+
9 rows in set (0.00 sec)(3)大于、小于
-- 查询用户ID大于9的记录
mysql> select * from users where user_id > 9;
+---------+------------+----------+--------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+------------+----------+--------------------+-------------+---------------------+
| 10 | chen_shier | 38 | chen12@example.com | 13800138010 | 2026-07-29 13:55:25 |
+---------+------------+----------+--------------------+-------------+---------------------+
1 row in set (0.00 sec)
-- 查询用户ID小于2的记录
mysql> select * from users where user_id < 2;
+---------+-----------+----------+----------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+-----------+----------+----------------------+-------------+---------------------+
| 1 | zhang_san | 23 | zhangsan@example.com | 13800138001 | 2026-07-29 13:55:25 |
+---------+-----------+----------+----------------------+-------------+---------------------+
1 row in set (0.00 sec)(3)大于等于、小于等于
-- 查询用户ID大于等于9的记录
mysql> select * from users where user_id >= 9;
+---------+-------------+----------+---------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+-------------+----------+---------------------+-------------+---------------------+
| 9 | zheng_shiyi | 22 | zheng11@example.com | 13800138009 | 2026-07-29 13:55:25 |
| 10 | chen_shier | 38 | chen12@example.com | 13800138010 | 2026-07-29 13:55:25 |
+---------+-------------+----------+---------------------+-------------+---------------------+
2 rows in set (0.00 sec)
-- 查询用户ID小于等于2的记录
mysql> select * from users where user_id <= 2;
+---------+-----------+----------+----------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+-----------+----------+----------------------+-------------+---------------------+
| 1 | zhang_san | 23 | zhangsan@example.com | 13800138001 | 2026-07-29 13:55:25 |
| 2 | li_si | 28 | lisi@example.com | 13800138002 | 2026-07-29 13:55:25 |
+---------+-----------+----------+----------------------+-------------+---------------------+
2 rows in set (0.00 sec)BETWEEN ... AND ... 用于闭区间范围查询,筛选字段的值大于等于下限,并且小于等于上限,包含两端边界值。
语法如下:
WHERE 字段 BETWEEN 下限值 AND 上限值;等价于
WHERE 字段 >= 下限值 AND 字段 <= 上限值;例如:
-- 查询用户ID在2和3之间的用户信息
mysql> select * from users where user_id between 2 and 3;
+---------+----------+----------+--------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+----------+----------+--------------------+-------------+---------------------+
| 2 | li_si | 28 | lisi@example.com | 13800138002 | 2026-07-29 13:55:25 |
| 3 | wang_wu | 35 | wangwu@example.com | 13800138003 | 2026-07-29 13:55:25 |
+---------+----------+----------+--------------------+-------------+---------------------+
2 rows in set (0.00 sec)
-- 等同于
mysql> select * from users where user_id>=2 and user_id<=3;
+---------+----------+----------+--------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+----------+----------+--------------------+-------------+---------------------+
| 2 | li_si | 28 | lisi@example.com | 13800138002 | 2026-07-29 13:55:25 |
| 3 | wang_wu | 35 | wangwu@example.com | 13800138003 | 2026-07-29 13:55:25 |
+---------+----------+----------+--------------------+-------------+---------------------+
2 rows in set (0.00 sec)
-- 查询2026-07-29日的用户数据
mysql> select * from users where created_at between '2026-07-29 00:00:00' and '2026-07-29 23:59:59';
+---------+-------------+----------+----------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+-------------+----------+----------------------+-------------+---------------------+
| 1 | zhang_san | 23 | zhangsan@example.com | 13800138001 | 2026-07-29 13:55:25 |
| 2 | li_si | 28 | lisi@example.com | 13800138002 | 2026-07-29 13:55:25 |
| 3 | wang_wu | 35 | wangwu@example.com | 13800138003 | 2026-07-29 13:55:25 |
| 4 | zhao_liu | 19 | zhaoliu@example.com | NULL | 2026-07-29 13:55:25 |
| 5 | qian_qi | 42 | qianqi@example.com | 13800138005 | 2026-07-29 13:55:25 |
| 6 | sun_ba | 26 | sunba@example.com | 13800138006 | 2026-07-29 13:55:25 |
| 7 | zhou_jiu | 31 | zhoujiu@example.com | NULL | 2026-07-29 13:55:25 |
| 8 | wu_shi | 50 | wushi@example.com | 13800138008 | 2026-07-29 13:55:25 |
| 9 | zheng_shiyi | 22 | zheng11@example.com | 13800138009 | 2026-07-29 13:55:25 |
| 10 | chen_shier | 38 | chen12@example.com | 13800138010 | 2026-07-29 13:55:25 |
+---------+-------------+----------+----------------------+-------------+---------------------+
10 rows in set (0.00 sec)
-- 查询用户ID不在2和3之间的用户信息
mysql> select * from users where user_id not between 2 and 3;
+---------+-------------+----------+----------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+-------------+----------+----------------------+-------------+---------------------+
| 1 | zhang_san | 23 | zhangsan@example.com | 13800138001 | 2026-07-29 13:55:25 |
| 4 | zhao_liu | 19 | zhaoliu@example.com | NULL | 2026-07-29 13:55:25 |
| 5 | qian_qi | 42 | qianqi@example.com | 13800138005 | 2026-07-29 13:55:25 |
| 6 | sun_ba | 26 | sunba@example.com | 13800138006 | 2026-07-29 13:55:25 |
| 7 | zhou_jiu | 31 | zhoujiu@example.com | NULL | 2026-07-29 13:55:25 |
| 8 | wu_shi | 50 | wushi@example.com | 13800138008 | 2026-07-29 13:55:25 |
| 9 | zheng_shiyi | 22 | zheng11@example.com | 13800138009 | 2026-07-29 13:55:25 |
| 10 | chen_shier | 38 | chen12@example.com | 13800138010 | 2026-07-29 13:55:25 |
+---------+-------------+----------+----------------------+-------------+---------------------+
8 rows in set (0.00 sec)IN 用来判断字段的值是否存在于给定的集合列表当中,只要等于列表中任意一个值,该行就会被查询出来。
语法如下:
WHERE 字段 IN (值1, 值2, 值3, ...);等价于多个 OR 条件拼接。
例如:
-- 查询特定城市的用户
mysql> select * from users where user_id in(1,3,5);
+---------+-----------+----------+----------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+-----------+----------+----------------------+-------------+---------------------+
| 1 | zhang_san | 23 | zhangsan@example.com | 13800138001 | 2026-07-29 13:55:25 |
| 3 | wang_wu | 35 | wangwu@example.com | 13800138003 | 2026-07-29 13:55:25 |
| 5 | qian_qi | 42 | qianqi@example.com | 13800138005 | 2026-07-29 13:55:25 |
+---------+-----------+----------+----------------------+-------------+---------------------+
3 rows in set (0.00 sec)
-- 等同于
mysql> select * from users where user_id=1 or user_id=3 or user_id=5;
+---------+-----------+----------+----------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+-----------+----------+----------------------+-------------+---------------------+
| 1 | zhang_san | 23 | zhangsan@example.com | 13800138001 | 2026-07-29 13:55:25 |
| 3 | wang_wu | 35 | wangwu@example.com | 13800138003 | 2026-07-29 13:55:25 |
| 5 | qian_qi | 42 | qianqi@example.com | 13800138005 | 2026-07-29 13:55:25 |
+---------+-----------+----------+----------------------+-------------+---------------------+
3 rows in set (0.00 sec)如果要筛选出不在集合中的数据,可以使用 NOT IN,例如:
mysql> select * from users where user_id not in(2,4,6,7,8,9,10);
+---------+-----------+----------+----------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+-----------+----------+----------------------+-------------+---------------------+
| 1 | zhang_san | 23 | zhangsan@example.com | 13800138001 | 2026-07-29 13:55:25 |
| 3 | wang_wu | 35 | wangwu@example.com | 13800138003 | 2026-07-29 13:55:25 |
| 5 | qian_qi | 42 | qianqi@example.com | 13800138005 | 2026-07-29 13:55:25 |
+---------+-----------+----------+----------------------+-------------+---------------------+
3 rows in set (0.00 sec)在 MySQL 中,NULL 代表未知、没有数据,它不等于 0、不等于空字符串'',也不能使用 =、<> 来判断。
错误写法:
WHERE phone = NULL; -- 永远查不到数据
WHERE phone <> NULL; -- 永远查不到数据正确写法:只能使用 IS NULL、IS NOT NULL
语法如下:
-- 查询该字段为NULL(值为空,未填写)
WHERE 字段 IS NULL;
-- 查询该字段不为NULL(有数据)
WHERE 字段 IS NOT NULL;例如:
-- 查询电话phone为null的用户数据
mysql> select * from users where phone is null;
+---------+----------+----------+---------------------+-------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+----------+----------+---------------------+-------+---------------------+
| 4 | zhao_liu | 19 | zhaoliu@example.com | NULL | 2026-07-29 13:55:25 |
| 7 | zhou_jiu | 31 | zhoujiu@example.com | NULL | 2026-07-29 13:55:25 |
+---------+----------+----------+---------------------+-------+---------------------+
2 rows in set (0.00 sec)
-- 查询电话phone不为null的用户数据
mysql> select * from users where phone is not null;
+---------+-------------+----------+----------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+-------------+----------+----------------------+-------------+---------------------+
| 1 | zhang_san | 23 | zhangsan@example.com | 13800138001 | 2026-07-29 13:55:25 |
| 2 | li_si | 28 | lisi@example.com | 13800138002 | 2026-07-29 13:55:25 |
| 3 | wang_wu | 35 | wangwu@example.com | 13800138003 | 2026-07-29 13:55:25 |
| 5 | qian_qi | 42 | qianqi@example.com | 13800138005 | 2026-07-29 13:55:25 |
| 6 | sun_ba | 26 | sunba@example.com | 13800138006 | 2026-07-29 13:55:25 |
| 8 | wu_shi | 50 | wushi@example.com | 13800138008 | 2026-07-29 13:55:25 |
| 9 | zheng_shiyi | 22 | zheng11@example.com | 13800138009 | 2026-07-29 13:55:25 |
| 10 | chen_shier | 38 | chen12@example.com | 13800138010 | 2026-07-29 13:55:25 |
+---------+-------------+----------+----------------------+-------------+---------------------+
8 rows in set (0.00 sec)LIKE 用于字符串的模糊匹配,一般配合两个通配符使用,用在 WHERE 子句中,用来做搜索功能。
语法如下:
WHERE 字符串字段 LIKE '匹配模板';模糊查询支持两个通配符:
% 匹配任意多个字符(包括零个)
_ 匹配单个字符
例如:
-- 查询用户姓名以“zh”开头的用户信息
mysql> select * from users where username like 'zh%';
+---------+-------------+----------+----------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+-------------+----------+----------------------+-------------+---------------------+
| 1 | zhang_san | 23 | zhangsan@example.com | 13800138001 | 2026-07-29 13:55:25 |
| 4 | zhao_liu | 19 | zhaoliu@example.com | NULL | 2026-07-29 13:55:25 |
| 7 | zhou_jiu | 31 | zhoujiu@example.com | NULL | 2026-07-29 13:55:25 |
| 9 | zheng_shiyi | 22 | zheng11@example.com | 13800138009 | 2026-07-29 13:55:25 |
+---------+-------------+----------+----------------------+-------------+---------------------+
4 rows in set (0.00 sec)
-- 查询用户年龄以2开头的用户信息,年龄两位数
mysql> select * from users where user_age like '2_';
+---------+-------------+----------+----------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+-------------+----------+----------------------+-------------+---------------------+
| 1 | zhang_san | 23 | zhangsan@example.com | 13800138001 | 2026-07-29 13:55:25 |
| 2 | li_si | 28 | lisi@example.com | 13800138002 | 2026-07-29 13:55:25 |
| 6 | sun_ba | 26 | sunba@example.com | 13800138006 | 2026-07-29 13:55:25 |
| 9 | zheng_shiyi | 22 | zheng11@example.com | 13800138009 | 2026-07-29 13:55:25 |
+---------+-------------+----------+----------------------+-------------+---------------------+
4 rows in set (0.00 sec)NOT LIKE 是 LIKE 的取反,用来查询不满足模糊匹配规则的数据行。例如:
-- 查询用户姓名不以 zh 开头的用户信息
mysql> select * from users where username not like 'zh%';
+---------+------------+----------+--------------------+-------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+------------+----------+--------------------+-------------+---------------------+
| 2 | li_si | 28 | lisi@example.com | 13800138002 | 2026-07-29 13:55:25 |
| 3 | wang_wu | 35 | wangwu@example.com | 13800138003 | 2026-07-29 13:55:25 |
| 5 | qian_qi | 42 | qianqi@example.com | 13800138005 | 2026-07-29 13:55:25 |
| 6 | sun_ba | 26 | sunba@example.com | 13800138006 | 2026-07-29 13:55:25 |
| 8 | wu_shi | 50 | wushi@example.com | 13800138008 | 2026-07-29 13:55:25 |
| 10 | chen_shier | 38 | chen12@example.com | 13800138010 | 2026-07-29 13:55:25 |
+---------+------------+----------+--------------------+-------------+---------------------+
6 rows in set (0.00 sec)% 和 _ 在 LIKE 里面是通配符,拥有特殊含义。如果数据表字符串里本身就包含字符 % 或者 _,想要把它当做普通字符来匹配,就需要转义。
比如用户名:张%三、李_四,直接写下面 SQL 是错误的:
-- 错误:%会被当成通配符,不是匹配百分号本身
SELECT * FROM users WHERE username LIKE '张%三';上面 '张%三' 中%代表任意多个字符,含义变成:张开头,三结尾,并不是匹配文字张%三。
转义使用反斜杠 \,例如:
-- 匹配字符串中真实的 % 符号
WHERE username LIKE '%\%%';
-- 匹配字符串中真实的 _ 下划线
WHERE username LIKE '%\_%';