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
就是查询条件,它的结果是一个布尔值,其值可能为 TRUE
, FALSE
或 UNKNOWN
。最终, SELECT
语句返回的结果集就是满足查询条件结果为 TRUE
的记录。
查询条件一般用来比较某个字段是否匹配某个值,一般形式如下:
ini
column_name = value
查询条件也可以是使用 AND
, OR
和 NOT
逻辑运算符一个或多个表达式的组合。
除了用在 SELECT
语句之外, WHERE
子句还可以用在 UPDATE
和 DELETE
语句中,用来指定要更新或删除的行。
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
子句查找姓为 ALLEN
或 DAVIS
的所有演员:
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
子句还可以用在 UPDATE
和 DELETE
语句中。