本章将详细介绍 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)
我们检索Name
和Cost
列。 列名用逗号分隔。
重命名列名
我们可以重命名返回结果集的列名。 为此,我们使用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)
假设我们要命名列价格而不是成本。 通过上面的 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
表中选择名称,成本列,然后按汽车成本降序对其进行排序。 因此,最昂贵的汽车排在第一位。
使用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 字符开头的客户。 我们可以看到布朗两次被提及。 要删除重复项,我们使用DISTINCT
关键字。
mysql> SELECT DISTINCT Customer FROM Orders WHERE Customer LIKE 'B%';
+----------+
| Customer |
+----------+
| Brown |
| Black |
+----------+
2 rows in set (0.00 sec)
这是正确的解决方案。
假设我们想算出布朗客户下了多少订单。 我们将利用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 为 2040 订购了 440 或 Smith 的商品。
使用聚合函数时,不能使用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
语句将数据加载回表中。 我们验证数据是否正确加载。