MySQL SELECT 语句

本文介绍了 MySQL 中的 SELECT 语句的基本形式,以及如何使用 SELECT 语句从数据库中查询数据。

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

SELECT 语句语法

以下是 SELECT 语句的语法:

SELECT columns_list
FROM table_name;

说明:

  • 关键字 SELECT 后跟着一个或多个数据表的列。
  • columns_list 可以有多个列,他们之间需要用逗号 , 分隔。
  • 当要检索数据表中的所有列的时候,使用 SELECT * FROM table_name
  • 关键字 FROM 后跟着要从中检索数据的表名。
  • 分号 ; 表示语句的结束,它是可选的。如果有两条或更多条语句,则需要使用分号 ; 将它们分开,以便 MySQL 单独执行每条语句。

将 SQL 关键字书写为大写形式是一个好的编码习惯。但是,SQL 不区分大小写。比如下面的语句也是完全正确执行的:

select columns_list
from table_name;

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

SELECT 语句实例

我们使用 Sakila 示例数据库中的演员表 actor 作为演示。以下是 actor 表的定义:

+-------------+-------------------+------+-----+-------------------+-----------------------------------------------+
| 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 条数据,如下:

+----------+-------------+--------------+---------------------+
| 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):

SELECT
    last_name
FROM
    actor;

以下是部分输出:

+--------------+
| last_name    |
+--------------+
| AKROYD       |
| AKROYD       |
| AKROYD       |
| ALLEN        |
| ALLEN        |
| ALLEN        |
| ASTAIRE      |
| BACALL       |
...

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

使用 SELECT 语句查询多个字段

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

SELECT
    first_name, last_name
FROM
    actor;

以下是部分输出:

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

使用 SELECT 语句查询所有字段

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

SELECT
    *
FROM
    actor

以下是部分输出:

+----------+-------------+--------------+---------------------+
| 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 子句。语法如下:

SELECT expression_list

比如下面的这几种情况:

  • 查询系统时间

    SELECT NOW();
    
    +---------------------+
    | NOW()               |
    +---------------------+
    | 2021-09-07 22:45:33 |
    +---------------------+
    1 row in set (0.00 sec)
  • 数值计算

    SELECT 1+2;
    
    +-----+
    | 1+2 |
    +-----+
    |   3 |
    +-----+
    1 row in set (0.00 sec)

虚拟表 dual

像上面的没有 FROM 子句的情况,也可以添加一个虚拟表 dual。如下所示:

SELECT NOW() FROM dual;
SELECT 1+2 FROM dual;

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

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

结论

本文通过实例介绍了 MySQL 中 SELECT 语句的语法,用法。 SELECT 语句的要点如下:

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