W SQL Server ROW_NUMBER()
funkcja pozwala na numerowanie wyjścia zestawu wyników. Zwraca kolejny numer każdego wiersza, zaczynając od 1.
Jeśli określisz partycje dla zestawu wyników, każda partycja spowoduje, że numeracja rozpocznie się od nowa (tj. numeracja rozpocznie się od 1 dla pierwszego wiersza w każdej partycji).
Składnia
Składnia wygląda tak:
ROW_NUMBER ( ) OVER ( [ PARTITION BY value_expression , ... [ n ] ] order_by_clause )
PARTITION BY value_expression
jest opcjonalne. Dzieli zestaw wyników utworzony przez FROM
klauzuli na przegrody, do których funkcja jest stosowana. wartość_wyrażenia określa kolumnę, według której zestaw wyników jest podzielony na partycje. Jeśli PARTITION BY
klauzula nie jest określona, wszystkie wiersze zestawu wyników zapytania są traktowane jako jedna grupa.
ROW_NUMBER
w określonej partycji.
Zauważ, że OVER
klauzula normalnie akceptuje klauzulę
Przykład 1 – Podstawowe użycie
Oto podstawowy przykład pokazujący, jak działa ta funkcja:
SELECT ROW_NUMBER() OVER (ORDER BY AlbumId ASC) 'Row', AlbumId, AlbumName FROM Albums;
Wynik:
+-------+-----------+--------------------------+ | 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 | +-------+-----------+--------------------------+
W tym przypadku widzimy, że numery wierszy są idealnie dopasowane do wartości w AlbumId
kolumna. To czysty przypadek. Dzieje się tak, ponieważ AlbumId
kolumna używa wartości zwiększającej się zaczynając od 1, co jest również tym, co ROW_NUMBER()
zastosowań.
Numeracja wierszy jest skorelowana z AlbumId
kolumna w zakresie, w jakim jest uporządkowana według tej kolumny. Ale to nie znaczy, że wartości muszą być takie same.
Przykład 2 – Dodaj klauzulę WHERE
Dodawanie WHERE
klauzula pokaże, o co mi chodzi.
SELECT ROW_NUMBER() OVER (ORDER BY AlbumId ASC) 'Row', AlbumId, AlbumName FROM Albums WHERE AlbumId > 15;
Wynik:
+-------+-----------+-------------------------+ | 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 | +-------+-----------+-------------------------+
Przykład 3 – Zmiana kolejności
Kolejność według kolejności malejącej zamiast rosnącej również demonstruje tę koncepcję.
SELECT ROW_NUMBER() OVER (ORDER BY AlbumId DESC) 'Row', AlbumId, AlbumName FROM Albums;
Wynik:
+-------+-----------+--------------------------+ | 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 | +-------+-----------+--------------------------+
Przykład 4 – Zamów według innej kolumny
A skoro już przy tym jesteśmy, zamówmy według AlbumName
zamiast tego kolumna.
SELECT ROW_NUMBER() OVER (ORDER BY AlbumName ASC) 'Row', AlbumId, AlbumName FROM Albums;
Wynik:
+-------+-----------+--------------------------+ | 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 | +-------+-----------+--------------------------+
Przykład 5 – Partycje
Jak wspomniano, wyniki można również podzielić na partycje. Gdy to zrobisz, numeracja zaczyna się ponownie od 1 dla każdej nowej partycji.
Przykład:
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;
Wynik:
+---------+-------+-----------+--------------------------+ | 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 | +---------+-------+-----------+--------------------------+
Po raz kolejny widzimy, że ROW_NUMBER
i AlbumId
kolumny są całkowicie nieskorelowane.
W tym przypadku dzielę według Genre
kolumna. Powoduje to, że numeracja zaczyna się ponownie od 1 dla każdego gatunku.