MySQL SELECT 语句和使用 WHERE 子句过滤数据

MySQL SELECT 语句

SELECT 语句用于从一个或多个表中检索数据,是 MySQL 中使用最多的语句。

SELECT 语句语法

sql 复制代码
SELECT columns_list FROM table_name;

说明:

关键字 SELECT 后跟着一个或多个数据表的列。

columns_list 可以有多个列,他们之间需要用逗号 , 分隔。

当要检索数据表中的所有列的时候,使用 SELECT * FROM table_name

关键字 FROM 后跟着要从中检索数据的表名。

分号 ; 表示语句的结束,它是可选的。如果有两条或更多条语句,则需要使用分号 ; 将它们分开,以便 MySQL 单独执行每条语句。

SELECT 语句的正确语义应是 FROM table_name SELECT columns_list,即:从某个表检索某几列数据。MySQL 解析 SELECT 语句的时候,会首先评估 FROM 子句,再评估 SELECT 子句。

SELECT 语句实例

我们使用 Sakila 示例数据库中的演员表 actor 作为演示。

sql 复制代码
+-------------+-------------------+------+-----+-------------------+-----------------------------------------------+
| Field       | Type              | Null | Key | Default           | Extra                                         |
+-------------+-------------------+------+-----+-------------------+-----------------------------------------------+
| actor_id    | smallint unsigned | NO   | PRI | NULL              | auto_increment                                |
| first_name  | varchar(45)       | NO   |     | NULL              |                                               |
| last_name   | varchar(45)       | NO   | MUL | NULL              |                                               |
| last_update | timestamp         | NO   |     | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP |
+-------------+-------------------+------+-----+-------------------+-----------------------------------------------+
​

从中我们可以看到 actor 表中定义了 4 个字段: actor_id, first_name, last_name, last_update

actor 表中总共有 200 条数据,如下:

yaml 复制代码
+----------+-------------+--------------+---------------------+
| actor_id | first_name  | last_name    | last_update         |
+----------+-------------+--------------+---------------------+
|        1 | PENELOPE    | GUINESS      | 2006-02-15 04:34:33 |
|        2 | NICK        | WAHLBERG     | 2006-02-15 04:34:33 |
|        3 | ED          | CHASE        | 2006-02-15 04:34:33 |
|        4 | JENNIFER    | DAVIS        | 2006-02-15 04:34:33 |
|        5 | JOHNNY      | LOLLOBRIGIDA | 2006-02-15 04:34:33 |
|        6 | BETTE       | NICHOLSON    | 2006-02-15 04:34:33 |
...
|      198 | MARY        | KEITEL       | 2006-02-15 04:34:33 |
|      199 | JULIA       | FAWCETT      | 2006-02-15 04:34:33 |
|      200 | THORA       | TEMPLE       | 2006-02-15 04:34:33 |
+----------+-------------+--------------+---------------------+

使用 SELECT 语句查询一个字段

以下 SELECT 语句从 actor 表选择所有演员的姓氏(last_name):

sql 复制代码
SELECT last_name FROM actor;

以下是部分输出:

diff 复制代码
+--------------+
| last_name    |
+--------------+
| AKROYD       |
| AKROYD       |
| AKROYD       |
| ALLEN        |
| ALLEN        |
| ALLEN        |
| ASTAIRE      |
| BACALL       |
...
​

一个结果 SELECT 语句被称为结果集,因为它是一组行从查询结果。

使用 SELECT 语句查询多个字段

以下 SELECT 语句从 actor 表选择所有演员的名字 (first_name) 和姓氏 (last_name):

sql 复制代码
SELECT first_name,last_name FROM actor;

以下是部分输出:

diff 复制代码
+-------------+--------------+
| first_name  | last_name    |
+-------------+--------------+
| PENELOPE    | GUINESS      |
| NICK        | WAHLBERG     |
| ED          | CHASE        |
| JENNIFER    | DAVIS        |
| JOHNNY      | LOLLOBRIGIDA |
| BETTE       | NICHOLSON    |
| GRACE       | MOSTEL       |
| MATTHEW     | JOHANSSON    |
...

使用 SELECT 语句查询所有字段

使用以下 SELECT 语句查询演员表中的所有字段:

sql 复制代码
SELECT * FROM actor;

以下是部分输出:

yaml 复制代码
+----------+-------------+--------------+---------------------+
| actor_id | first_name  | last_name    | last_update         |
+----------+-------------+--------------+---------------------+
|        1 | PENELOPE    | GUINESS      | 2006-02-15 04:34:33 |
|        2 | NICK        | WAHLBERG     | 2006-02-15 04:34:33 |
|        3 | ED          | CHASE        | 2006-02-15 04:34:33 |
|        4 | JENNIFER    | DAVIS        | 2006-02-15 04:34:33 |
|        5 | JOHNNY      | LOLLOBRIGIDA | 2006-02-15 04:34:33 |
|        6 | BETTE       | NICHOLSON    | 2006-02-15 04:34:33 |
...
|      198 | MARY        | KEITEL       | 2006-02-15 04:34:33 |
|      199 | JULIA       | FAWCETT      | 2006-02-15 04:34:33 |
|      200 | THORA       | TEMPLE       | 2006-02-15 04:34:33 |
+----------+-------------+--------------+---------------------+

也可以列出所有字段的名字,并使用逗号 , 分隔开。

SELECT *SELECT column_name 有什么区别呢?就一般而言,两者的性能差不多。就区别而言,有如下不同:

1.写出明确的字段,更容易理解你的 SQL 的查询意图

2.某些大字段不适合直接查询出来,因为直接查询会占用更多的开销

3.SELECT * 更适合在命令行或者测试场景下使用

没有 FROM 的 SELECT

在 MySQL 中,某些情况下你要检索的数据不存在于任何表中,这时您可以省略 FROM 子句。语法如下:

ini 复制代码
SELECT expression_list;

比如下面的这几种情况:

查询系统时间

csharp 复制代码
SELECT NOW();
sql 复制代码
+---------------------+
| NOW()               |
+---------------------+
| 2025-03-25 10:11:22 |
+---------------------+
1 row in set (0.00 sec)

数值计算

ini 复制代码
SELECT 1+2;
sql 复制代码
+-----+
| 1+2 |
+-----+
|   3 |
+-----+
1 row in set (0.00 sec)

虚拟表 dual

像上面的没有 FROM 子句的情况,也可以添加一个虚拟表 dual

sql 复制代码
SELECT NOW() FROM dual;
SELECT 1+2 FROM dual;

运算结果和上面的实例完全相同。

dual 表是一个虚拟表,完全可以忽略。它存在的目的只是让你的 SQL 看起来更加工整。

总结

SELECT 语句的要点如下:

  • SELECT 语句用于从数据表中检索数据。

    • SELECT 关键字后跟字段的名称,多个字段使用逗号分隔。
    • FROM 关键字后跟数据表的名称。
    • SELECT * 可以从表的所有列中选择数据。
    • SELECT 后面可以直接跟表达式,这种情况下可以省略 FROM
    • dual 表是一个虚拟表,可以让没有 FROM 的语句满足 SELECT ... FROM 语句的结构。

MySQL 使用 WHERE 子句过滤数据

默认情况下,SELECT 查询数据表中的所有行数。但我们只想查询满足一定条件的数据,就要用到 WHERE 子句。

MySQL WHERE 子句介绍

WHERE 子句允许您为 SELECT 查询指定搜索条件。以下是 WHERE 子句的语法:

sql 复制代码
SELECT columns_list FROM table_name WHERE query_condition;

其中 query_condition 就是查询条件,它的结果是一个布尔值,其值可能为 TRUEFALSEUNKNOWN。最终, SELECT 语句返回的结果集就是满足查询条件结果为 TRUE 的记录。

查询条件一般用来比较某个字段是否匹配某个值,一般形式如下:

ini 复制代码
column_name = value

查询条件也可以是使用 AND , ORNOT 逻辑运算符一个或多个表达式的组合。

除了用在 SELECT 语句之外, WHERE 子句还可以用在 UPDATEDELETE 语句中,用来指定要更新或删除的行。

WHERE 子句实例

在以下实例中,我们使用 Sakila 示例数据库中的演员表 actor 作为演示。

以下是 actor 表的定义:

sql 复制代码
+-------------+-------------------+------+-----+-------------------+-----------------------------------------------+
| Field       | Type              | Null | Key | Default           | Extra                                         |
+-------------+-------------------+------+-----+-------------------+-----------------------------------------------+
| actor_id    | smallint unsigned | NO   | PRI | NULL              | auto_increment                                |
| first_name  | varchar(45)       | NO   |     | NULL              |                                               |
| last_name   | varchar(45)       | NO   | MUL | NULL              |                                               |
| last_update | timestamp         | NO   |     | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP |
+-------------+-------------------+------+-----+-------------------+-----------------------------------------------+
​

使用相等比较运算

以下查询使用 WHERE 子句查找姓为 ALLEN 的所有演员:

ini 复制代码
SELECT * FROM actor WHERE last_name = 'ALLEN';

在这个语句中查询条件 last_name = 'ALLEN' 的含义是表中记录行的 last_name 字段的值为 ALLEN

sql 复制代码
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update         |
+----------+------------+-----------+---------------------+
|      118 | CUBA       | ALLEN     | 2006-02-15 04:34:33 |
|      145 | KIM        | ALLEN     | 2006-02-15 04:34:33 |
|      194 | MERYL      | ALLEN     | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+
17 rows in set (0.00 sec)

查询结果显示了 actor 表中姓为 ALLEN 的所有演员的信息,共有 3 条符合条件的记录。

使用 AND 组合多个条件查询

以下查询使用 WHERE 子句查找姓为 DAVIS 名为 SUSAN 的所有演员:

ini 复制代码
SELECT * FROM actor WHERE last_name = 'DAVIS' AND first_name = 'SUSAN';

在这个语句中,查询条件 last_name = 'DAVIS' AND first_name = 'SUSAN' 的意思是过滤表中 last_name 字段的值为 DAVIS,并且 first_name 字段的值为 SUSAN 的所有记录行。

last_name = 'DAVIS' 是一个条件,first_name = 'SUSAN' 也是一个条件,AND 将两者组合在一起,意思是查询的记录行要同时满足这两个条件。

AND 两边的条件表达式,必须两个表达式都返回了 TRUE,整个表达式的结果才是 TRUE

sql 复制代码
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update         |
+----------+------------+-----------+---------------------+
|      101 | SUSAN      | DAVIS     | 2006-02-15 04:34:33 |
|      110 | SUSAN      | DAVIS     | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+
2 rows in set (0.00 sec)

从返回的结果集来看,只有 2 条记录满足查询条件。

使用 OR 组合多个查询条件

以下查询使用 WHERE 子句查找姓为 ALLENDAVIS 的所有演员:

ini 复制代码
SELECT * FROM actor WHERE last_name = 'ALLEN' OR last_name = 'DAVIS';
yaml 复制代码
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update         |
+----------+------------+-----------+---------------------+
|      118 | CUBA       | ALLEN     | 2006-02-15 04:34:33 |
|      145 | KIM        | ALLEN     | 2006-02-15 04:34:33 |
|      194 | MERYL      | ALLEN     | 2006-02-15 04:34:33 |
|        4 | JENNIFER   | DAVIS     | 2006-02-15 04:34:33 |
|      101 | SUSAN      | DAVIS     | 2006-02-15 04:34:33 |
|      110 | SUSAN      | DAVIS     | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+

在这个语句中,查询条件 last_name = 'ALLEN' OR last_name = 'DAVIS' 代表了表中记录行的 last_name 字段的记录值等于 ALLEN 或者 DAVIS

OR 两边的条件表达式,只要一个表达式返回了 TRUE,整个表达式的结果就是 TRUE

比较运算符

在上面的几个例子中,我们只使用了一种比较运算符 = 。 比较运算符 = 的作用是比较运算符两边的操作数(字段或表达式或值)是否相等。

MySQL 提供了很多比较运算符以满足各种不同比较需求。下表列出了可用于 WHERE 子句中的比较运算符。

比较运算符 说明 举例
= 等于 age = 18
<> 不等于 age <> 18
!= 不等于 age != 18
> 大于,通常用于比较数字或者日期 age > 18
>= 大于等于,通常用于比较数字或者日期 age >= 18
< 小于,通常用于比较数字或者日期 age < 18
<= 小于等于,通常用于比较数字或者日期 age <= 18
IN 判断值是否在一个集合中 age IN (18, 19)
NOT IN 判断值是否不在一个集合中 age NOT IN (18, 19)
BETWEEN 判断值是否介于两个数中间 age BETWEEN 16 AND 18
LIKE 模糊匹配 name LIKE 'A%'
IS NULL 是否为 NULL name IS NULL
IS NOT NULL 是否不为 NULL name IS NOT NULL

注意: 在 SQL 中,比较两个值是否相等的运算符是 =,而不是 ==。这与一些常见的编程语言并不相同。

结论

SELECT 语句中使用 WHERE 子句进行条件查询。

WHERE 子句可以使用多种比较运算符。

WHERE 子句可以使用 AND, OR, NOT 组合多种条件。

WHERE 子句还可以用在 UPDATEDELETE 语句中。

相关推荐
珹洺6 分钟前
Jsp技术入门指南【十四】实现基于MySQL+JDBC+JSP数据库验证的登录界面与登录跳转功能
java·运维·数据库·mysql·servlet
JhonKI14 分钟前
【MySQL】日志缓冲区详解 以及 InnoDB内存结构总结
数据库·mysql·oracle
vvilkim1 小时前
MySQL视图:虚拟表的强大功能与应用实践
数据库·mysql
tangjunjun-owen1 小时前
Milvus 2.4 使用详解:从零构建向量数据库并实现搜索功能(Python 实战)
数据库·python·milvus·rag
GalenZhang8881 小时前
langchain4j中使用milvus向量数据库做RAG增加索引
数据库·milvus
闪电麦坤951 小时前
思路解析:第一性原理解 SQL
服务器·数据库·sql
珹洺2 小时前
数据库系统概论(八)SQL单表查询语言超详细讲解(附带例题表格对比带你一步步掌握)
数据库·sql
斌果^O^2 小时前
mysql常用方法
数据库·mysql
全职计算机毕业设计2 小时前
SpringBoot Vue MySQL酒店民宿预订系统源码(支付宝沙箱支付)+代码讲解视频
vue.js·spring boot·mysql
man20172 小时前
基于ssm+mysql的高校设备管理系统(含LW+PPT+源码+系统演示视频+安装说明)
数据库·mysql·ssm