💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# MySQL 中的`SELECT`语句 > 原文: [http://zetcode.com/databases/mysqltutorial/select/](http://zetcode.com/databases/mysqltutorial/select/) MySQL 教程的这一部分将详细介绍 MySQL 理解的`SELECT`语句。 ## 检索数据 以下 SQL 语句是最常见的语句之一。 它也是最昂贵的之一。 ```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`字。 ```sql 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`子句。 ```sql 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`子句来限制该语句返回的数据量。 ```sql 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`有两个参数,返回从偏移值开始的行。 ```sql 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) ``` 第一个值是偏移量,第二个值是要返回的行数。 在这里,我们从最多四行中选择所有数据,然后从第三行开始。 ```sql 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`则以降序对数据进行排序。 ```sql 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`表。 ```sql 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`表中的所有数据。 接下来,我们要选择一个特定的行。 ```sql mysql> SELECT * FROM Orders WHERE Id=6; +----+------------+------------+ | Id | OrderPrice | Customer | +----+------------+------------+ | 6 | 50 | Williamson | +----+------------+------------+ 1 row in set (0.00 sec) ``` 上面的 SQL 语句选择具有 ID 6 的行。 ```sql 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`关键字在数据中查找特定的模式。 ```sql 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`关键字仅用于从结果集中选择唯一项。 ```sql mysql> SELECT Customer FROM Orders WHERE Customer LIKE 'B%'; +----------+ | Customer | +----------+ | Brown | | Black | | Brown | +----------+ 3 rows in set (0.00 sec) ``` 这次,我们选择了名称以 B 字符开头的客户。 我们可以看到布朗两次被提及。 要删除重复项,我们使用`DISTINCT`关键字。 ```sql mysql> SELECT DISTINCT Customer FROM Orders WHERE Customer LIKE 'B%'; +----------+ | Customer | +----------+ | Brown | | Black | +----------+ 2 rows in set (0.00 sec) ``` 这是正确的解决方案。 假设我们想算出布朗客户下了多少订单。 我们将利用`COUNT()`函数。 ```sql 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`子句用于将具有相同值的数据库记录组合到单个记录中。 它通常与聚合函数一起使用。 说我们想找出每个客户的订单总和。 ```sql 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`子句。 ```sql 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`语句可用于将表中的数据写入文件。 ```sql 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(逗号分隔值)文件。 请注意,此操作容易出错,我们很容易遇到权限被拒绝的错误。 ```sql $ 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 ``` 我们可以做相反的操作; 将文件中的数据加载到表中。 ```sql mysql> DELETE FROM Cars; Query OK, 8 rows affected (0.00 sec) mysql> SELECT * FROM Cars; Empty set (0.00 sec) ``` 我们从`Cars`表中删除所有行。 ```sql 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`语句。