MySQL 添加序号
MySQL 添加序号
简介:在本教程中,您将学习如何在 MySQL 中模拟 row_number()
函数。我们将向您展示如何为结果集中的每一行或每组行添加唯一编号。
请注意,MySQL 支持 ROW_NUMBER()
自 8.0 版以来的版本。如果您使用 MySQL 8.0 或更高版本,请检查它的 ROW_NUMBER()
功能。否则,您可以继续学习本教程以了解如何模拟 ROW_NUMBER()
功能。
row_number 函数简介
这 row_number()
是一个排名函数,它返回一行的序号,从第一行的 1 开始。您经常希望使用 row_number()
函数来生成特定报告。 版本低于 8.0 的 MySQL 不支持 row_number()
就像 Microsoft SQL Server,Oracle 或 PostgreSQL 一样。幸运的是,MySQL 提供了可用于模拟 row_number()
函数的会话变量 。
MySQL row_number - 为每一行添加一个行号
要模拟 row_number()
函数,您必须在查询中使用会话变量。 以下语句从 employees
表中获取 5 名员工, 并从 1 开始为每行添加行号。
SET @row_number = 0;
SELECT
( @row_number := @row_number + 1 ) AS num,
firstName,
lastName
FROM
employees
LIMIT 5;
+------+-----------+-----------+
| num | firstName | lastName |
+------+-----------+-----------+
| 1 | Diane | Murphy |
| 2 | Mary | Phan |
| 3 | Jeff | Firrelli |
| 4 | William | Patterson |
| 5 | Gerard | Bondur |
+------+-----------+-----------+
5 rows in set (0.00 sec)
在上面的陈述中:
- 在第一个语句中,我们定义了一个名为的变量
row_number
,并将其值设置为 0. 这row_number
是由@
前缀指示的会话变量。 - 在第二个语句中,我们从
employees
表中选择数据,并将每行的row_number
变量值增加到 1。LIMIT
子句用于约束返回的行数,在这种情况下,它被设置为 5。
另一种技术是使用会话变量作为派生表,并将其与主表交叉连接。请参阅以下查询:
SELECT
(@row_number:=@row_number + 1) AS num, firstName, lastName
FROM
employees,(SELECT @row_number:=0) AS t
LIMIT 5;
请注意,派生表必须具有自己的别名,以使查询在语法上正确。
MySQL row_number - 为每个组添加行号
row_number()
OVER PARTITION BY
功能怎么样 ?例如,如果要为每个组添加行号,并为每个新组重置行,怎么办? 我们来看看示例数据库中的 payments
表:
+----------------+
| payments |
+----------------+
| customerNumber |
| checkNumber |
| paymentDate |
| amount |
+----------------+
4 rows in set (0.00 sec)
SELECT
customerNumber, paymentDate, amount
FROM
payments
ORDER BY customerNumber;
+----------------+-------------+-----------+
| customerNumber | paymentDate | amount |
+----------------+-------------+-----------+
| 103 | 2014-10-19 | 6066.78 |
| 103 | 2013-06-05 | 14571.44 |
| 103 | 2014-12-18 | 1676.14 |
| 112 | 2014-12-17 | 14191.12 |
| 112 | 2013-06-06 | 32641.98 |
| 112 | 2014-08-20 | 33347.88 |
| 114 | 2013-05-20 | 45864.03 |
| 114 | 2014-12-15 | 82261.22 |
...
假设您为每个客户添加一个行号,并在客户编号更改时重置行号。 要实现此目的,您必须使用两个会话变量,一个用于行号,另一个用于存储旧客户编号,以将其与当前的客户编号进行比较,如下面的查询:
SELECT
@row_number :=
IF( @customer_no = customerNumber, @row_number + 1, 1 ) AS num,
@customer_no := customerNumber AS CustomerNumber,
paymentDate,
amount
FROM
payments
ORDER BY
customerNumber;
我们在查询中使用了 IF 函数。如果客户编号保持不变,我们增加了 row_number
变量,否则,我们将其重置为 1。查询结果如下面的屏幕截图所示。
+------+----------------+-------------+-----------+
| num | CustomerNumber | paymentDate | amount |
+------+----------------+-------------+-----------+
| 1 | 103 | 2014-10-19 | 6066.78 |
| 2 | 103 | 2013-06-05 | 14571.44 |
| 3 | 103 | 2014-12-18 | 1676.14 |
| 1 | 112 | 2014-12-17 | 14191.12 |
| 2 | 112 | 2013-06-06 | 32641.98 |
| 3 | 112 | 2014-08-20 | 33347.88 |
| 1 | 114 | 2013-05-20 | 45864.03 |
| 2 | 114 | 2014-12-15 | 82261.22 |
| 3 | 114 | 2013-05-31 | 7565.08 |
| 4 | 114 | 2014-03-10 | 44894.74 |
| 1 | 119 | 2014-11-14 | 19501.82 |
| 2 | 119 | 2014-08-08 | 47924.19 |
| 3 | 119 | 2015-02-22 | 49523.67 |
...
与 row_number
每行一样,您可以使用派生表和交叉连接技术来生成相同的结果。
SELECT
@row_number:=CASE
WHEN @customer_no = customerNumber THEN @row_number + 1
ELSE 1
END AS num,
@customer_no:=customerNumber as CustomerNumber,
paymentDate,
amount
FROM
payments,(SELECT @customer_no:=0,@row_number:=0) as t
ORDER BY customerNumber;
在本教程中,我们向您展示了如何在 MySQL 中模拟 row_number
函数。