Trong SQL Server, ROW_NUMBER()
cho phép bạn đánh số đầu ra của một tập kết quả. Nó trả về số thứ tự của mỗi hàng, bắt đầu từ 1.
Nếu bạn chỉ định phân vùng cho tập hợp kết quả, mỗi phân vùng sẽ làm cho việc đánh số bắt đầu lại (tức là việc đánh số sẽ bắt đầu từ 1 cho hàng đầu tiên trong mỗi phân vùng).
Cú pháp
Cú pháp như sau:
ROW_NUMBER ( ) OVER ( [ PARTITION BY value_expression , ... [ n ] ] order_by_clause )
PARTITION BY value_expression
Là tùy chọn. Nó chia tập hợp kết quả được tạo ra bởi FROM
mệnh đề thành các phân vùng mà hàm được áp dụng. value_expression chỉ định cột mà tập kết quả được phân vùng. Nếu PARTITION BY
mệnh đề không được chỉ định, tất cả các hàng của tập kết quả truy vấn được coi là một nhóm duy nhất.
ROW_NUMBER
duy nhất của chúng trong một phân vùng được chỉ định.
Lưu ý rằng OVER
mệnh đề thường chấp nhận
Ví dụ 1 - Cách sử dụng cơ bản
Dưới đây là một ví dụ cơ bản cho thấy chức năng này hoạt động như thế nào:
SELECT ROW_NUMBER() OVER (ORDER BY AlbumId ASC) 'Row', AlbumId, AlbumName FROM Albums;
Kết quả:
+-------+-----------+--------------------------+ | Row | AlbumId | AlbumName | |-------+-----------+--------------------------| | 1 | 1 | Powerslave | | 2 | 2 | Powerage | | 3 | 3 | Singing Down the Lane | | 4 | 4 | Ziltoid the Omniscient | | 5 | 5 | Casualties of Cool | | 6 | 6 | Epicloud | | 7 | 7 | Somewhere in Time | | 8 | 8 | Piece of Mind | | 9 | 9 | Killers | | 10 | 10 | No Prayer for the Dying | | 11 | 11 | No Sound Without Silence | | 12 | 12 | Big Swing Face | | 13 | 13 | Blue Night | | 14 | 14 | Eternity | | 15 | 15 | Scandinavia | | 16 | 16 | Long Lost Suitcase | | 17 | 17 | Praise and Blame | | 18 | 18 | Along Came Jones | | 19 | 19 | All Night Wrong | | 20 | 20 | The Sixteen Men of Tain | | 21 | 21 | Yo Wassup | | 22 | 22 | Busted | +-------+-----------+--------------------------+
Trong trường hợp này, chúng ta có thể thấy rằng số hàng căn chỉnh hoàn hảo với các giá trị trong AlbumId
cột. Đây hoàn toàn là sự trùng hợp ngẫu nhiên. Điều này xảy ra vì AlbumId
đang sử dụng giá trị tăng dần bắt đầu từ 1, cũng là giá trị ROW_NUMBER()
sử dụng.
Việc đánh số hàng có liên quan đến AlbumId
trong phạm vi mà nó được sắp xếp theo cột đó. Nhưng điều đó không có nghĩa là các giá trị cần phải giống nhau.
Ví dụ 2 - Thêm mệnh đề WHERE
Thêm WHERE
mệnh đề sẽ chứng minh những gì tôi muốn nói.
SELECT ROW_NUMBER() OVER (ORDER BY AlbumId ASC) 'Row', AlbumId, AlbumName FROM Albums WHERE AlbumId > 15;
Kết quả:
+-------+-----------+-------------------------+ | Row | AlbumId | AlbumName | |-------+-----------+-------------------------| | 1 | 16 | Long Lost Suitcase | | 2 | 17 | Praise and Blame | | 3 | 18 | Along Came Jones | | 4 | 19 | All Night Wrong | | 5 | 20 | The Sixteen Men of Tain | | 6 | 21 | Yo Wassup | | 7 | 22 | Busted | +-------+-----------+-------------------------+
Ví dụ 3 - Chuyển đổi Thứ tự
Sắp xếp theo thứ tự giảm dần thay vì tăng dần cũng thể hiện khái niệm này.
SELECT ROW_NUMBER() OVER (ORDER BY AlbumId DESC) 'Row', AlbumId, AlbumName FROM Albums;
Kết quả:
+-------+-----------+--------------------------+ | Row | AlbumId | AlbumName | |-------+-----------+--------------------------| | 1 | 22 | Busted | | 2 | 21 | Yo Wassup | | 3 | 20 | The Sixteen Men of Tain | | 4 | 19 | All Night Wrong | | 5 | 18 | Along Came Jones | | 6 | 17 | Praise and Blame | | 7 | 16 | Long Lost Suitcase | | 8 | 15 | Scandinavia | | 9 | 14 | Eternity | | 10 | 13 | Blue Night | | 11 | 12 | Big Swing Face | | 12 | 11 | No Sound Without Silence | | 13 | 10 | No Prayer for the Dying | | 14 | 9 | Killers | | 15 | 8 | Piece of Mind | | 16 | 7 | Somewhere in Time | | 17 | 6 | Epicloud | | 18 | 5 | Casualties of Cool | | 19 | 4 | Ziltoid the Omniscient | | 20 | 3 | Singing Down the Lane | | 21 | 2 | Powerage | | 22 | 1 | Powerslave | +-------+-----------+--------------------------+
Ví dụ 4 - Thứ tự theo một cột khác
Và trong khi chúng ta đang ở đó, hãy đặt hàng theo AlbumName
thay vào đó.
SELECT ROW_NUMBER() OVER (ORDER BY AlbumName ASC) 'Row', AlbumId, AlbumName FROM Albums;
Kết quả:
+-------+-----------+--------------------------+ | Row | AlbumId | AlbumName | |-------+-----------+--------------------------| | 1 | 19 | All Night Wrong | | 2 | 18 | Along Came Jones | | 3 | 12 | Big Swing Face | | 4 | 13 | Blue Night | | 5 | 22 | Busted | | 6 | 5 | Casualties of Cool | | 7 | 6 | Epicloud | | 8 | 14 | Eternity | | 9 | 9 | Killers | | 10 | 16 | Long Lost Suitcase | | 11 | 10 | No Prayer for the Dying | | 12 | 11 | No Sound Without Silence | | 13 | 8 | Piece of Mind | | 14 | 2 | Powerage | | 15 | 1 | Powerslave | | 16 | 17 | Praise and Blame | | 17 | 15 | Scandinavia | | 18 | 3 | Singing Down the Lane | | 19 | 7 | Somewhere in Time | | 20 | 20 | The Sixteen Men of Tain | | 21 | 21 | Yo Wassup | | 22 | 4 | Ziltoid the Omniscient | +-------+-----------+--------------------------+
Ví dụ 5 - Phân vùng
Như đã đề cập, bạn cũng có thể chia kết quả thành các phân vùng. Khi bạn làm điều này, việc đánh số bắt đầu lại từ 1 cho mỗi phân vùng mới.
Ví dụ:
SELECT Genre, ROW_NUMBER() OVER (PARTITION BY Genre ORDER BY AlbumId ASC) 'Row', AlbumId, AlbumName FROM Albums INNER JOIN Genres ON Albums.GenreId = Genres.GenreId;
Kết quả:
+---------+-------+-----------+--------------------------+ | Genre | Row | AlbumId | AlbumName | |---------+-------+-----------+--------------------------| | Country | 1 | 3 | Singing Down the Lane | | Country | 2 | 21 | Yo Wassup | | Country | 3 | 22 | Busted | | Jazz | 1 | 12 | Big Swing Face | | Jazz | 2 | 19 | All Night Wrong | | Jazz | 3 | 20 | The Sixteen Men of Tain | | Pop | 1 | 11 | No Sound Without Silence | | Pop | 2 | 13 | Blue Night | | Pop | 3 | 14 | Eternity | | Pop | 4 | 15 | Scandinavia | | Pop | 5 | 16 | Long Lost Suitcase | | Pop | 6 | 17 | Praise and Blame | | Pop | 7 | 18 | Along Came Jones | | Rock | 1 | 1 | Powerslave | | Rock | 2 | 2 | Powerage | | Rock | 3 | 4 | Ziltoid the Omniscient | | Rock | 4 | 5 | Casualties of Cool | | Rock | 5 | 6 | Epicloud | | Rock | 6 | 7 | Somewhere in Time | | Rock | 7 | 8 | Piece of Mind | | Rock | 8 | 9 | Killers | | Rock | 9 | 10 | No Prayer for the Dying | +---------+-------+-----------+--------------------------+
Một lần nữa, chúng ta có thể thấy rằng ROW_NUMBER
và AlbumId
các cột hoàn toàn không tương quan.
Trong trường hợp này, tôi phân vùng theo Genre
cột. Điều này làm cho việc đánh số bắt đầu lại từ 1 cho mỗi thể loại.