MySQL ROW_NUMBER

时间:2019-11-20 08:52:32  来源:igfitidea点击:

简介:在本教程中,您将学习如何在MySQL中模拟row_number()函数。
我们将向您展示如何向结果集中的每一行或每一组行添加一个顺序整数。

请注意,自8.0版开始,MySQL已支持ROW_NUMBER()。
如果使用MySQL 8.0或更高版本,请签出ROW_NUMBER()函数。
否则,您可以继续学习本教程,以学习如何模拟ROW_NUMBER()函数。

ROW_NUMBER()函数简介

ROW_NUMBER()是一个窗口函数,为每行返回一个序号,从第一行的1开始。

在8.0版之前,MySQL不支持ROW_NUMBER()函数,例如Microsoft SQL Server,Oracle或PostgreSQL。
幸运的是,MySQL提供了可用于模拟ROW_NUMBER()函数的会话变量。

MySQL ROW_NUMBER –为每行添加一个行号

要模拟ROW_NUMBER()函数,您必须在查询中使用会话变量。

以下语句从employee表中返回五位雇员,并从1开始为每行添加行号。

SET @row_number = 0; 
SELECT 
    (@row_number:=@row_number + 1) AS num, 
    firstName, 
    lastName
FROM
    employees
ORDER BY firstName, lastName    
LIMIT 5;

在此示例中:

  • 首先,定义一个名为@row_number的变量并将其值设置为0。
    @ro​​w_number是由@前缀指示的会话变量。

  • 然后,从表employees中选择数据,并为每行将@row_number变量的值增加一。
    我们使用LIMIT子句将返回的行数限制为5。

另一种技术是将会话变量用作派生表,并将其与主表交叉连接。
请参阅以下查询:

SELECT 
    (@row_number:=@row_number + 1) AS num, 
    firstName, 
    lastName
FROM
    employees,
    (SELECT @row_number:=0) AS t
ORDER BY 
    firstName, 
    lastName    
LIMIT 5;

请注意,派生表必须具有自己的别名,以使查询在语法上正确。

MySQL ROW_NUMBER –向每个组添加行号

ROW_NUMBER()OVER(PARITION BY ...)功能怎么样?例如,如果您想向每个组添加行号,然后为每个新组重置行号怎么办。

让我们看一下示例数据库中的付款表:

SELECT
    customerNumber, 
    paymentDate, 
    amount
FROM
    payments
ORDER BY 
   customerNumber;

假设您想为每个客户添加一个行号,并且每当客户号更改时,行号都会重置。

为此,您必须使用两个会话变量,一个用于行号,另一个用于存储旧客户号,以将其与当前客户号进行比较,如下所示:

set @row_number := 0;

SELECT 
    @row_number:=CASE
        WHEN @customer_no = customerNumber 
			THEN @row_number + 1
        ELSE 1
    END AS num,
    @customer_no:=customerNumber customerNumber,
    paymentDate,
    amount
FROM
    payments
ORDER BY customerNumber;

在此示例中,我们在查询中使用CASE表达式。
如果客户编号保持不变,则增加@row_number变量,否则将其重置为1。

该查询使用派生表和交叉联接产生相同的结果。

SELECT 
    @row_number:=CASE
        WHEN @customer_no = customerNumber 
          THEN 
              @row_number + 1
          ELSE 
               1
        END AS num,
    @customer_no:=customerNumber CustomerNumber,
    paymentDate,
    amount
FROM
    payments,
    (SELECT @customer_no:=0,@row_number:=0) as t
ORDER BY 
    customerNumber;

在本教程中,您学习了两种在MySQL中模拟row_number窗口函数的方法。