sql >> Database teknologi >  >> RDS >> Sqlserver

Sådan fungerer ROW_NUMBER() i SQL Server

I SQL Server er ROW_NUMBER() funktionen giver dig mulighed for at nummerere outputtet af et resultatsæt. Det returnerer det sekventielle nummer for hver række, startende ved 1.

Hvis du angiver partitioner for resultatsættet, får hver partition nummereringen til at starte forfra (dvs. nummereringen starter ved 1 for den første række i hver partition).

Syntaks

Syntaksen ser sådan ud:

ROW_NUMBER ( )   
    OVER ( [ PARTITION BY value_expression , ... [ n ] ] order_by_clause )

PARTITION BY value_expression er valgfri. Den deler resultatsættet produceret af FROM klausul i partitioner, som funktionen anvendes på. værdiudtryk angiver den kolonne, som resultatsættet er opdelt efter. Hvis PARTITION BY klausulen ikke er angivet, behandles alle rækker i forespørgselsresultatsættet som en enkelt gruppe.

er påkrævet. Det bestemmer rækkefølgen, hvori rækkerne tildeles deres unikke ROW_NUMBER inden for en specificeret partition.

Bemærk, at OVER klausul accepterer normalt en , men det argument kan ikke bruges med denne funktion.

Eksempel 1 – Grundlæggende brug

Her er et grundlæggende eksempel, der viser, hvordan denne funktion fungerer:

SELECT
  ROW_NUMBER() OVER (ORDER BY AlbumId ASC) 'Row',
  AlbumId,
  AlbumName
FROM Albums;

Resultat:

+-------+-----------+--------------------------+
| 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                   |
+-------+-----------+--------------------------+

I dette tilfælde kan vi se, at rækkenumrene passer perfekt med værdierne i AlbumId kolonne. Dette er rent tilfældigt. Dette sker, fordi AlbumId kolonne bruger en stigende værdi, der starter ved 1, hvilket også er hvad ROW_NUMBER() bruger.

Rækkenummereringen er korreleret til AlbumId kolonne i det omfang, den er sorteret efter den pågældende kolonne. Men det betyder ikke, at værdierne skal være de samme.

Eksempel 2 – Tilføj en WHERE-klausul

Tilføjelse af en WHERE klausul vil vise, hvad jeg mener.

SELECT
  ROW_NUMBER() OVER (ORDER BY AlbumId ASC) 'Row',
  AlbumId,
  AlbumName
FROM Albums
WHERE AlbumId > 15;

Resultat:

+-------+-----------+-------------------------+
| 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                  |
+-------+-----------+-------------------------+

Eksempel 3 – Skift bestilling

Ordning efter faldende rækkefølge i stedet for stigende demonstrerer også dette koncept.

SELECT
  ROW_NUMBER() OVER (ORDER BY AlbumId DESC) 'Row',
  AlbumId,
  AlbumName
FROM Albums;

Resultat:

+-------+-----------+--------------------------+
| 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               |
+-------+-----------+--------------------------+

Eksempel 4 – Bestil efter en anden kolonne

Og mens vi er i gang, lad os bestille efter AlbumName kolonne i stedet.

SELECT
  ROW_NUMBER() OVER (ORDER BY AlbumName ASC) 'Row',
  AlbumId,
  AlbumName
FROM Albums;

Resultat:

+-------+-----------+--------------------------+
| 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   |
+-------+-----------+--------------------------+

Eksempel 5 – Partitioner

Som nævnt kan du også opdele resultaterne i partitioner. Når du gør dette, starter nummereringen ved 1 igen for hver ny partition.

Eksempel:

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;

Resultat:

+---------+-------+-----------+--------------------------+
| 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  |
+---------+-------+-----------+--------------------------+

Endnu en gang kan vi se, at ROW_NUMBER og AlbumId kolonner er fuldstændig ukorrelerede.

I dette tilfælde opdeler jeg efter Genre kolonne. Dette får nummereringen til at starte ved 1 igen for hver genre.


  1. Hvordan fjerner man tidsdelen af ​​en datetime-værdi (SQL-server)?

  2. Django-migreringsfejl:Kolonnen eksisterer ikke

  3. Få adgang til fejlnummermeddelelsesopslag

  4. docker postgres med indledende data er ikke persisted over commits