# 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`语句。