ZetCode

MySQL SELECT 语句

最后修改于 2023 年 1 月 10 日

MySQL 教程的这一部分将详细介绍 MySQL 理解的 SELECT 语句。

检索数据

以下 SQL 语句是最常见的语句之一。它也是最昂贵的语句之一。

mysql> SELECT * FROM Cars;
+----+------------+--------+
| Id | Name       | Cost   |
+----+------------+--------+
|  1 | Audi       |  52642 |
|  2 | Mercedes   |  57127 |
|  3 | Skoda      |   9000 |
|  4 | Volvo      |  29000 |
|  5 | Bentley    | 350000 |
|  6 | Citroen    |  21000 |
|  7 | Hummer     |  41400 |
|  8 | Volkswagen |  21600 |
+----+------------+--------+
8 rows in set (0.00 sec)

这里我们从 Cars 表中检索所有数据。

选择特定列

我们可以使用 SELECT 语句来检索特定列。列名紧随 SELECT 关键字之后。

mysql> SELECT Name, Cost FROM Cars;
+------------+--------+
| Name       | Cost   |
+------------+--------+
| Audi       |  52642 |
| Mercedes   |  57127 |
| Skoda      |   9000 |
| Volvo      |  29000 |
| Bentley    | 350000 |
| Citroen    |  21000 |
| Hummer     |  41400 |
| Volkswagen |  21600 |
+------------+--------+
8 rows in set (0.00 sec) 

我们检索 NameCost 列。列名之间用逗号分隔。

重命名列名

我们可以重命名返回结果集的列名。为此,我们使用 AS 子句。

mysql> SELECT Name, Cost AS Price FROM Cars;
+------------+--------+
| Name       | Price  |
+------------+--------+
| Audi       |  52642 |
| Mercedes   |  57127 |
| Skoda      |   9000 |
| Volvo      |  29000 |
| Bentley    | 350000 |
| Citroen    |  21000 |
| Hummer     |  41400 |
| Volkswagen |  21600 |
+------------+--------+
8 rows in set (0.00 sec)

假设我们想将列名命名为 price 而不是 cost。使用上面的 SQL 语句,我们已经完成了这个操作。

限制数据输出

正如我们上面提到的,当处理大量数据时,检索所有数据是昂贵的。我们可以使用 LIMIT 子句来限制语句返回的数据量。

mysql> SELECT * FROM Cars LIMIT 4;
+----+----------+-------+
| Id | Name     | Cost  |
+----+----------+-------+
|  1 | Audi     | 52642 |
|  2 | Mercedes | 57127 |
|  3 | Skoda    |  9000 |
|  4 | Volvo    | 29000 |
+----+----------+-------+
4 rows in set (0.00 sec) 

LIMIT 子句将返回的行数限制为 4。

使用两个参数,LIMIT 从偏移量开始返回行。

mysql> SELECT * FROM Cars LIMIT 2, 4;
+----+---------+--------+
| Id | Name    | Cost   |
+----+---------+--------+
|  3 | Skoda   |   9000 |
|  4 | Volvo   |  29000 |
|  5 | Bentley | 350000 |
|  6 | Citroen |  21000 |
+----+---------+--------+
4 rows in set (0.00 sec)   

第一个值是偏移量,第二个是返回的行数。这里我们选择最多四行的数据,我们从第三行开始。

mysql> SELECT * FROM Cars LIMIT 4 OFFSET 2;
+----+---------+--------+
| Id | Name    | Cost   |
+----+---------+--------+
|  3 | Skoda   |   9000 |
|  4 | Volvo   |  29000 |
|  5 | Bentley | 350000 |
|  6 | Citroen |  21000 |
+----+---------+--------+
4 rows in set (0.00 sec)

为了与 PostgreSQL 数据库兼容,MySQL 也有 OFFSET 关键字。上面的代码与之前的例子等效。

排序数据

我们使用 ORDER BY 子句对返回的数据集进行排序。ORDER BY 子句之后是进行排序的列。ASC 关键字按升序排序数据,DESC 按降序排序。

mysql> SELECT Name, Cost FROM Cars ORDER BY Cost DESC;
+------------+--------+
| Name       | Cost   |
+------------+--------+
| Bentley    | 350000 |
| Mercedes   |  57127 |
| Audi       |  52642 |
| Hummer     |  41400 |
| Volvo      |  29000 |
| Volkswagen |  21600 |
| Citroen    |  21000 |
| Skoda      |   9000 |
+------------+--------+
8 rows in set (0.00 sec)

在上面的 SQL 语句中,我们从 Cars 表中选择 name, cost 列,并按汽车的成本降序排序。所以最贵的车排在最前面。

使用 WHERE 子句选择特定行

在下面的例子中,我们将使用 Orders 表。

mysql> SELECT * FROM Orders;
+----+------------+------------+
| Id | OrderPrice | Customer   |
+----+------------+------------+
|  1 |       1200 | Williamson |
|  2 |        200 | Robertson  |
|  3 |         40 | Robertson  |
|  4 |       1640 | Smith      |
|  5 |        100 | Robertson  |
|  6 |         50 | Williamson |
|  7 |        150 | Smith      |
|  8 |        250 | Smith      |
|  9 |        840 | Brown      |
| 10 |        440 | Black      |
| 11 |         20 | Brown      |
+----+------------+------------+
11 rows in set (0.00 sec)

这里我们看到 Orders 表中的所有数据。

接下来,我们要选择一个特定的行。

mysql> SELECT * FROM Orders WHERE Id=6;
+----+------------+------------+
| Id | OrderPrice | Customer   |
+----+------------+------------+
|  6 |         50 | Williamson |
+----+------------+------------+
1 row in set (0.00 sec)

上面的 SQL 语句选择 Id 为 6 的行。

mysql> SELECT * FROM Orders WHERE Customer="Smith";
+----+------------+----------+
| Id | OrderPrice | Customer |
+----+------------+----------+
|  4 |       1640 | Smith    |
|  7 |        150 | Smith    |
|  8 |        250 | Smith    |
+----+------------+----------+
3 rows in set (0.00 sec)

上面的 SQL 语句选择由 Smith 客户创建的所有订单。

我们可以使用 LIKE 关键字在数据中查找特定的模式。

mysql> SELECT * FROM Orders WHERE Customer LIKE "B%";
+----+------------+----------+
| Id | OrderPrice | Customer |
+----+------------+----------+
|  9 |        840 | Brown    |
| 10 |        440 | Black    |
| 11 |         20 | Brown    |
+----+------------+----------+
3 rows in set (0.00 sec)

此 SQL 语句选择所有客户名称以 B 字符开头的订单。

删除重复项

DISTINCT 关键字用于仅从结果集中选择唯一项。

mysql> SELECT Customer FROM Orders WHERE Customer LIKE 'B%';
+----------+
| Customer |
+----------+
| Brown    |
| Black    |
| Brown    |
+----------+
3 rows in set (0.00 sec)

这次我们选择了名称以 B 字符开头的客户。我们可以看到 Brown 被提到了两次。要删除重复项,我们使用 DISTINCT 关键字。

mysql> SELECT DISTINCT Customer FROM Orders WHERE Customer LIKE 'B%';
+----------+
| Customer |
+----------+
| Brown    |
| Black    |
+----------+
2 rows in set (0.00 sec)

这是正确的解决方案。

假设我们想知道 Brown 客户下了多少个订单。我们将使用 COUNT() 函数。

mysql> SELECT COUNT(Customer) AS "Orders by Brown" FROM Orders WHERE Customer="Brown";
+-----------------+
| Orders by Brown |
+-----------------+
|               2 |
+-----------------+
1 row in set (0.00 sec)

该客户下了两个订单。

分组数据

GROUP BY 子句用于将具有相同值的数据库记录合并为一条记录。它经常与聚合函数一起使用。

假设我们想找出每个客户的订单总和。

mysql> SELECT SUM(OrderPrice) AS Total, Customer FROM Orders GROUP BY Customer;
+-------+------------+
| Total | Customer   |
+-------+------------+
|   440 | Black      |
|   860 | Brown      |
|   340 | Robertson  |
|  2040 | Smith      |
|  1250 | Williamson |
+-------+------------+
5 rows in set (0.00 sec)

SUM() 关键字返回数值列的总和。GROUP BY 子句将总和分配给客户。因此我们可以看到 Black 订购了 440 个物品或 Smith 订购了 2040 个物品。

当使用聚合函数时,我们不能使用 WHERE 子句。我们使用 HAVING 子句代替。

mysql> SELECT SUM(OrderPrice) AS Total, Customer FROM Orders
    -> GROUP BY Customer HAVING SUM(OrderPrice)>1000;
+-------+------------+
| Total | Customer   |
+-------+------------+
|  2040 | Smith      |
|  1250 | Williamson |
+-------+------------+
2 rows in set (0.00 sec)

上面的 SQL 语句选择总订单超过 1000 单元的客户。

将数据选择到文件中

SELECT 语句可用于将数据从表写入文件。

mysql> SELECT * INTO OUTFILE '/tmp/cars.txt'
    -> FIELDS TERMINATED BY ','
    -> LINES TERMINATED BY '\n'
    -> FROM Cars;
Query OK, 8 rows affected (0.00 sec)

我们将数据从 Cars 表写入 cars.txt 文件。输出文件是 CSV(逗号分隔值)文件。请注意,此操作容易出错,我们很容易遇到权限被拒绝的错误。

$ cat /tmp/cars.txt 
1,Audi,52642
2,Mercedes,57127
3,Skoda,9000
4,Volvo,29000
5,Bentley,350000
6,Citroen,21000
7,Hummer,41400
8,Volkswagen,21600

我们可以做相反的操作;将数据从文件加载到表中。

mysql> DELETE FROM Cars;
Query OK, 8 rows affected (0.00 sec)

mysql> SELECT * FROM Cars;
Empty set (0.00 sec)

我们从 Cars 表中删除所有行。

mysql> LOAD DATA INFILE '/tmp/cars.txt' 
    -> INTO TABLE Cars
    -> FIELDS TERMINATED BY ','
    -> LINES TERMINATED BY '\n';
Query OK, 8 rows affected (0.00 sec)
Records: 8  Deleted: 0  Skipped: 0  Warnings: 0

mysql> SELECT *  FROM Cars;
+----+------------+--------+
| Id | Name       | Cost   |
+----+------------+--------+
|  1 | Audi       |  52642 |
|  2 | Mercedes   |  57127 |
|  3 | Skoda      |   9000 |
|  4 | Volvo      |  29000 |
|  5 | Bentley    | 350000 |
|  6 | Citroen    |  21000 |
|  7 | Hummer     |  41400 |
|  8 | Volkswagen |  21600 |
+----+------------+--------+
8 rows in set (0.00 sec)

我们使用 LOAD DATA INFILE 语句将数据加载回表中。我们验证数据是否已正确加载。

在 MySQL 教程的这一部分中,我们更详细地提到了 SQL SELECT 语句。