Summary: in this tutorial, you will learn how to emulate the row_number()
function in MySQL. We will show you how to add a sequential integer to each row or group of rows in the result set.
Notice that MySQL has supported the ROW_NUMBER()
since version 8.0. If you use MySQL 8.0 or later, refer to the ROW_NUMBER()
function tutorial. Otherwise, you can continue with the tutorial to learn how to emulate the ROW_NUMBER()
function.
Introduction to the ROW_NUMBER() function
The ROW_NUMBER()
is a window function that returns a sequential number for each row, starting from 1 for the first row.
Before version 8.0, MySQL did not support ROW_NUMBER()
function like Microsoft SQL Server, Oracle, or PostgreSQL. Fortunately, MySQL provides session variables that you can use to emulate the ROW_NUMBER()
function.
MySQL ROW_NUMBER – adding a row number for each row
To emulate the ROW_NUMBER()
function, you have to use session variables in the query.
The following statements return five employees from the employees
table and add a row number to each row, starting from 1.
SET @row_number = 0;
SELECT
(@row_number:=@row_number + 1) AS num,
firstName,
lastName
FROM
employees
ORDER BY firstName, lastName
LIMIT 5;
Code language: SQL (Structured Query Language) (sql)
In this example:
- First, define a variable named
@row_number
and set its value to 0. The@row_number
is a session variable indicated by the@
prefix. - Then, select data from the table
employees
and increase the value of the@row_number
variable by one for each row. We use theLIMIT
clause to constrain a number of returned rows to five.
Another technique is to use a session variable as a derived table and cross join it with the main table. See the following query:
SELECT
(@row_number:=@row_number + 1) AS num,
firstName,
lastName
FROM
employees,
(SELECT @row_number:=0) AS t
ORDER BY
firstName,
lastName
LIMIT 5;
Code language: SQL (Structured Query Language) (sql)
Notice that the derived table must have its own alias to make the query syntactically correct.
MySQL ROW_NUMBER – adding a row number to each group
How about the ROW_NUMBER() OVER(PARITION BY ... )
functionality? For example, what if you want to add a row number to each group, and it is reset for every new group?
Let’s take a look at the payments
table from the sample database:
SELECT
customerNumber,
paymentDate,
amount
FROM
payments
ORDER BY
customerNumber;
Code language: SQL (Structured Query Language) (sql)
Suppose for each customer, you want to add a row number, and the row number is reset whenever the customer number changes.
To achieve this, you have to use two session variables, one for the row number and the other for storing the old customer number to compare it with the current one as the following query:
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;
Code language: SQL (Structured Query Language) (sql)
In this example, we use the CASE
expression in the query. If the customer number remains the same, we increase the @row_number
variable, otherwise, we reset it to one.
This query uses a derived table and the cross join to produce the same result.
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;
Code language: SQL (Structured Query Language) (sql)
In this tutorial, you have learned two ways to emulate the row_number
window function in MySQL.