SQL 查询数据:过滤数据(WHERE)

本章将介绍如何使用 SELECT 语句的 WHERE 子句指定过滤条件,过滤出我们想要的数据。

WHERE 子句语法

数据库表通常存储着海量数据,实际业务中极少需要检索表内的全部行数据。一般情况下,会根据具体的业务操作或报表需求,仅提取表中符合条件的数据子集。要精准检索所需数据,就需要指定搜索条件(也常被称作过滤条件)。

在 SELECT 语句中,数据会依据 WHERE 子句中定义的搜索条件进行筛选。WHERE 子句需紧跟在指定数据源的 FROM 子句(表名)之后,语法示例如下:

select * from user where gender='女'

输出如下:

user_id|name|gender|age|phone      |email               |address        |create_time        |update_time        |
-------+----+------+---+-----------+--------------------+---------------+-------------------+-------------------+
      2|李四  |女     | 30|13800138001|lisi@example.com    |上海市浦东新区张江路100号 |2025-01-18 14:22:00|2025-12-24 14:44:13|
      4|赵六  |女     | 22|13800138003|zhaoliu@example.com |深圳市南山区科技园10号   |2025-01-11 11:56:00|2025-12-24 14:44:13|
      6|周八  |女     | 27|13800138005|zhouba@example.com  |成都市武侯区武侯祠大街231号|2025-01-12 01:37:00|2025-12-24 14:44:13|
      8|郑十  |女     | 29|13800138007|zhengshi@example.com|武汉市武昌区中南路99号   |2025-01-26 19:22:00|2025-12-24 14:44:13|
     10|孙十二 |女     | 31|13800138009|                    |南京市玄武区玄武湖路78号  |2025-01-01 17:34:00|2025-12-24 14:44:13|

5 row(s) fetched.

上面的 SQL 语句将检索 user 表中性别(gender)为“女”的用户数据。

注意:

(1)上述 SQL 语句中的“=”表示等于。例如:gender='女' 表示 gender 等于“女”。

(2)在同时使用 ORDER BY 和 WHERE 子句时,应该让 ORDER BY 位于 WHERE 之后,否则将会产生错误。例如:

select * from user order by age where gender='女'

错入信息如下:

SQL 错误 [1064] [42000]: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where gender='女'' at line 1

WHERE 字句操作符

前面我们使用“=”符号进行相等性测试,下图是 WHERE 子句支持的所有条件操作符:

过滤数据(WHERE)

注意:上图中列出的某些操作符是冗余的,如 <> 与 != 相同,!<(不小于) 相当于 >=(大于等于)。而且,并不是所有 DBMS 都支持这些操作符。

检查单个值

前面我们已经看到了测试相等的例子。现在来看看几个使用其他操作符的例子:

(1)小于:年龄小于 25 岁的用户

select * from user where age<25

输出如下:

user_id|name|gender|age|phone      |email                |address     |create_time        |update_time        |
-------+----+------+---+-----------+---------------------+------------+-------------------+-------------------+
      4|赵六  |女     | 22|13800138003|zhaoliu@example.com  |深圳市南山区科技园10号|2025-01-11 11:56:00|2025-12-24 14:44:13|
      9|钱十一 |男     | 24|13800138008|qianshiyi@example.com|西安市雁塔区雁塔路15号|2025-01-22 15:08:00|2025-12-24 14:44:13|

2 row(s) fetched.

(2)小于等于:年龄小于等于 25 岁的用户

select * from user where age<=25

输出如下:

user_id|name|gender|age|phone      |email                |address     |create_time        |update_time        |
-------+----+------+---+-----------+---------------------+------------+-------------------+-------------------+
      1|张三  |男     | 25|13800138000|zhangsan@example.com |北京市朝阳区建国路88号|2025-01-24 02:41:00|2025-12-24 14:44:13|
      4|赵六  |女     | 22|13800138003|zhaoliu@example.com  |深圳市南山区科技园10号|2025-01-11 11:56:00|2025-12-24 14:44:13|
      9|钱十一 |男     | 24|13800138008|qianshiyi@example.com|西安市雁塔区雁塔路15号|2025-01-22 15:08:00|2025-12-24 14:44:13|

3 row(s) fetched.

(3)大于:年龄大于 25 岁的用户

select * from user where age>25

输出如下:

user_id|name|gender|age|phone      |email               |address        |create_time        |update_time        |
-------+----+------+---+-----------+--------------------+---------------+-------------------+-------------------+
      2|李四  |女     | 30|13800138001|lisi@example.com    |上海市浦东新区张江路100号 |2025-01-18 14:22:00|2025-12-24 14:44:13|
      3|王五  |男     | 28|13800138002|wangwu@example.com  |广州市天河区天河路385号  |2025-01-19 15:49:00|2025-12-24 14:44:13|
      5|孙七  |男     | 35|13800138004|                    |杭州市西湖区西湖路58号   |2025-01-27 12:17:00|2025-12-24 14:44:13|
      6|周八  |女     | 27|13800138005|zhouba@example.com  |成都市武侯区武侯祠大街231号|2025-01-12 01:37:00|2025-12-24 14:44:13|
      7|吴九  |      | 32|13800138006|wujiu@example.com   |重庆市渝中区解放碑路18号  |2025-01-06 19:15:00|2025-12-24 14:44:13|
      8|郑十  |女     | 29|13800138007|zhengshi@example.com|武汉市武昌区中南路99号   |2025-01-26 19:22:00|2025-12-24 14:44:13|
     10|孙十二 |女     | 31|13800138009|                    |南京市玄武区玄武湖路78号  |2025-01-01 17:34:00|2025-12-24 14:44:13|

7 row(s) fetched.

(4)大于等于:年龄大于等于 25 岁的用户

select * from user where age>=25

输出如下:

user_id|name|gender|age|phone      |email               |address        |create_time        |update_time        |
-------+----+------+---+-----------+--------------------+---------------+-------------------+-------------------+
      1|张三  |男     | 25|13800138000|zhangsan@example.com|北京市朝阳区建国路88号   |2025-01-24 02:41:00|2025-12-24 14:44:13|
      2|李四  |女     | 30|13800138001|lisi@example.com    |上海市浦东新区张江路100号 |2025-01-18 14:22:00|2025-12-24 14:44:13|
      3|王五  |男     | 28|13800138002|wangwu@example.com  |广州市天河区天河路385号  |2025-01-19 15:49:00|2025-12-24 14:44:13|
      5|孙七  |男     | 35|13800138004|                    |杭州市西湖区西湖路58号   |2025-01-27 12:17:00|2025-12-24 14:44:13|
      6|周八  |女     | 27|13800138005|zhouba@example.com  |成都市武侯区武侯祠大街231号|2025-01-12 01:37:00|2025-12-24 14:44:13|
      7|吴九  |      | 32|13800138006|wujiu@example.com   |重庆市渝中区解放碑路18号  |2025-01-06 19:15:00|2025-12-24 14:44:13|
      8|郑十  |女     | 29|13800138007|zhengshi@example.com|武汉市武昌区中南路99号   |2025-01-26 19:22:00|2025-12-24 14:44:13|
     10|孙十二 |女     | 31|13800138009|                    |南京市玄武区玄武湖路78号  |2025-01-01 17:34:00|2025-12-24 14:44:13|

8 row(s) fetched.

不匹配检查

以下例子列出性别(gender)不是“男”的所有用户:

select * from user where gender<>'男'

下面是相同的例子,其中使用 != 而不是 <> 操作符:

select * from user where gender!='男'

输出如下:

user_id|name|gender|age|phone      |email               |address        |create_time        |update_time        |
-------+----+------+---+-----------+--------------------+---------------+-------------------+-------------------+
      2|李四  |女     | 30|13800138001|lisi@example.com    |上海市浦东新区张江路100号 |2025-01-18 14:22:00|2025-12-24 14:44:13|
      4|赵六  |女     | 22|13800138003|zhaoliu@example.com |深圳市南山区科技园10号   |2025-01-11 11:56:00|2025-12-24 14:44:13|
      6|周八  |女     | 27|13800138005|zhouba@example.com  |成都市武侯区武侯祠大街231号|2025-01-12 01:37:00|2025-12-24 14:44:13|
      8|郑十  |女     | 29|13800138007|zhengshi@example.com|武汉市武昌区中南路99号   |2025-01-26 19:22:00|2025-12-24 14:44:13|
     10|孙十二 |女     | 31|13800138009|                    |南京市玄武区玄武湖路78号  |2025-01-01 17:34:00|2025-12-24 14:44:13|

5 row(s) fetched.

选择 != 还是 <> ?

!= 和 <>通常可以互换使用。但是,并非所有 DBMS 都支持这两种不等于操作符。例如,Microsoft Access 支持 <> 而不支持 !=。

范围值检查

为了检查某个范围的值,可使用 BETWEEN 操作符。其语法与其他 WHERE 子句的操作符稍有不同,因为它需要两个值,即范围的开始值和结束值。

例如:使用 BETWEEN 操作符查询年龄在 25 岁到 30 岁之间的所有用户。

select * from user where age BETWEEN 25 AND 30

输出如下:

user_id|name|gender|age|phone      |email               |address        |create_time        |update_time        |
-------+----+------+---+-----------+--------------------+---------------+-------------------+-------------------+
      1|张三  |男     | 25|13800138000|zhangsan@example.com|北京市朝阳区建国路88号   |2025-01-24 02:41:00|2025-12-24 14:44:13|
      2|李四  |女     | 30|13800138001|lisi@example.com    |上海市浦东新区张江路100号 |2025-01-18 14:22:00|2025-12-24 14:44:13|
      3|王五  |男     | 28|13800138002|wangwu@example.com  |广州市天河区天河路385号  |2025-01-19 15:49:00|2025-12-24 14:44:13|
      6|周八  |女     | 27|13800138005|zhouba@example.com  |成都市武侯区武侯祠大街231号|2025-01-12 01:37:00|2025-12-24 14:44:13|
      8|郑十  |女     | 29|13800138007|zhengshi@example.com|武汉市武昌区中南路99号   |2025-01-26 19:22:00|2025-12-24 14:44:13|

5 row(s) fetched.

从这个例子中可以看到,在使用 BETWEEN 时,必须指定两个值 —— 所需范围的低端和高端值。这两个值必须用 AND 关键字分隔。

注意:BETWEEN 将匹配范围中所有的值,包括指定的开始和结束值。

空值检查

在创建数据表时,表设计人员可明确指定列是否允许不存储具体值。当某列未存储任何值时,该列被认定为包含空值(NULL)。

需要注意的是,NULL 代表 “无值”(no value),它与字段中存储 0、空字符串('')或仅包含空格的情况有着本质区别 —— 后几种均属于存储了具体值,而 NULL 表示值的缺失。

在 SQL 的 SELECT 语句中,可通过一个专用的 WHERE 子句来检查列中是否包含 NULL 值,即 IS NULL 子句。其语法如下:

select * from user where gender is null

输出结果如下:

user_id|name|gender|age|phone      |email            |address      |create_time        |update_time        |
-------+----+------+---+-----------+-----------------+-------------+-------------------+-------------------+
      7|吴九  |      | 32|13800138006|wujiu@example.com|重庆市渝中区解放碑路18号|2025-01-06 19:15:00|2025-12-24 14:44:13|

1 row(s) fetched.

上面 SQL 语句将返回没有性别的所有用户。

  

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号