MySQL (trước phiên bản 8.0) không có hàm ROW_NUMBER(). Cách thay thế là sử dụng biến người dùng (user-defined variable).
Cú pháp (MySQL 5.7 trở xuống)
SELECT (@row_number := @row_number + 1) AS row_number, ten_cot1, ten_cot2 FROM ten_bang, (SELECT @row_number := 0) AS t;
Ví dụ minh họa
Tạo bảng và chèn dữ liệu:
mysql> CREATE TABLE RowNumberDemo (
-> UserId INT,
-> UserName VARCHAR(20)
-> );
mysql> INSERT INTO RowNumberDemo VALUES(10, 'John');
mysql> INSERT INTO RowNumberDemo VALUES(50, 'Carol');
mysql> INSERT INTO RowNumberDemo VALUES(100, 'Sam');
mysql> INSERT INTO RowNumberDemo VALUES(150, 'Mike');
mysql> INSERT INTO RowNumberDemo VALUES(210, 'Bob');
Sinh số thứ tự:
mysql> SELECT
-> (@ROW_NUMBER := @ROW_NUMBER + 1) AS `ROW_NUMBER`, UserId, UserName
-> FROM RowNumberDemo, (SELECT @ROW_NUMBER := 0) AS t;
Kết quả:
+------------+--------+----------+ | ROW_NUMBER | UserId | UserName | +------------+--------+----------+ | 1 | 10 | John | | 2 | 50 | Carol | | 3 | 100 | Sam | | 4 | 150 | Mike | | 5 | 210 | Bob | +------------+--------+----------+
MySQL 8.0+ : Hỗ trợ ROW_NUMBER() chuẩn
SELECT ROW_NUMBER() OVER (ORDER BY UserId) AS row_number, UserId, UserName FROM RowNumberDemo;
Ưu điểm của window function:
- Tiêu chuẩn SQL, dễ đọc, dễ bảo trì
- Hỗ trợ
PARTITION BYđể đánh số theo nhóm - Hiệu suất tốt hơn biến session
Ví dụ PARTITION BY:
SELECT ROW_NUMBER() OVER (PARTITION BY Department ORDER BY Salary DESC) AS rank_in_dept, * FROM Employees;