Anta att du designar en SQL Server-databasapplikation för ett företags VD och att du måste visa den femte högst betalda anställde i företaget.
Vad skulle du göra? En lösning är att skriva en fråga så här:
SELECT EmployeeName FROM Employees ORDER BY Salary DESC OFFSET 4 ROWS FETCH FIRST 1 ROWS ONLY;
Frågan ovan ser besvärlig ut, särskilt om du måste rangordna alla anställda. I så fall är en lösning att lista de anställda i fallande löneordning och sedan ta den anställdes index som rang. Det blir dock komplicerat om de flera anställda har samma lön. Hur skulle du ranka dem?
Som tur är kommer SQL Server med inbyggda rankningsfunktioner som kan användas för att rangordna poster på en mängd olika sätt. I den här artikeln kommer vi att introducera SQL-serverns rankningsfunktioner i detalj och illustrera det med exemplen.
Det finns fyra olika typer av rankningsfunktioner i SQL Server:
- Rank()
- Dense_Rank()
- Radnummer()
- Ntile()
Det är viktigt att nämna att alla rankningsfunktioner i SQL-servern kräver ORDER BY-satsen.
Innan vi tittar på var och en av rankningsfunktionerna i detalj, låt oss först skapa dummydata som vi kommer att använda i den här artikeln för att förklara rankningsfunktionen. Kör följande skript:
CREATE DATABASE Showroom Use Showroom CREATE TABLE Car ( CarId int identity(1,1) primary key, Name varchar(100), Make varchar(100), Model int , Price int , Type varchar(20) ) insert into Car( Name, Make, Model , Price, Type) VALUES ('Corrolla','Toyota',2015, 20000,'Sedan'), ('Civic','Honda',2018, 25000,'Sedan'), ('Passo','Toyota',2012, 18000,'Hatchback'), ('Land Cruiser','Toyota',2017, 40000,'SUV'), ('Corrolla','Toyota',2011, 17000,'Sedan'), ('Vitz','Toyota',2014, 15000,'Hatchback'), ('Accord','Honda',2018, 28000,'Sedan'), ('7500','BMW',2015, 50000,'Sedan'), ('Parado','Toyota',2011, 25000,'SUV'), ('C200','Mercedez',2010, 26000,'Sedan'), ('Corrolla','Toyota',2014, 19000,'Sedan'), ('Civic','Honda',2015, 20000,'Sedan')
I manuset ovan skapar vi Showroom-databas med ett bord Bil. Biltabellen har fem attribut:CarId, Name, Make, Model, Price och Type.
Därefter lade vi till 12 dummy-poster i tabellen Bil.
Nu ser du var och en av rankningsfunktionerna.
1. Rangfunktion
Rangfunktionen i SQL-servern tilldelar rankning till varje post sorterad av ORDER BY-satsen. Om du till exempel vill se den femte dyraste bilen i biltabellen kan du använda rankningsfunktionen enligt följande:
Use Showroom SELECT Name,Make,Model, Price, Type, RANK() OVER(ORDER BY Price DESC) as PriceRank FROM Car
I skriptet ovan väljer du namn, märke, modell, pris, typ och rangordningen för varje bil sorterad efter pris som kolumnen "PriceRank". Syntaxen för Rank-funktionen är enkel. Du måste skriva funktionen RANK följt av OVER-operatorn. Inuti OVER-operatorn måste du skicka ORDER BY-satsen som sorterar data. Utdata från skriptet ovan ser ut så här:
Du kan se rankningen för varje bil. Det är viktigt att nämna att om det är oavgjort mellan raden av två rekord, hoppas nästa rankningsposition över. Till exempel finns det en koppling mellan post 5 och 6 i utgången. Både Parado och Civic har lika priser, och har därför blivit rankade 5. Men nästa rankning, i synnerhet rank 6, hoppas över och de nästa två bilarna i listan har rankats 7 eftersom de också har samma pris. Efter 7:e rankningen hoppas rank 8 över igen och nästa tilldelade rankning är 9.
Du kan dela upp data i partitioner och sedan tillämpa rankning på enskilda partitioner. I följande skript finns uppdelningen av posterna efter typ. Vi rangordnar bilarna inuti varje partition.
SELECT Name,Make,Model, Price, Type, RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as PriceRank FROM Car
Utdata från skriptet ovan ser ut så här:
Det framgår av resultatet att posterna har delats upp efter biltyper och rangordningen har tilldelats lokalt inuti partitionen. Till exempel tillhör de två första posterna partitionen "Hatchback" och har rankats 1 och 2. För nästa partition, dvs. "Sedan", återställs rangen till 1.
2. Dense_Rank Function
Dense_rank-funktionen liknar rank-funktionen. Men i fallet med dense_rank, om det är oavgjort mellan två poster vad gäller rankningen, hoppas inte nästa rank över. Låt oss se demonstrera det med exemplet. Kör följande skript:
Use Showroom SELECT Name,Make,Model, Price, Type, DENSE_RANK() OVER(ORDER BY Price DESC) as DensePriceRank FROM Car
Återigen kan du se att den 5:e och 6:e posten har samma värde för Price och båda har tilldelats rang 5. Men till skillnad från rangfunktion som hoppade över nästa rang, hoppar dense_rank-funktionen inte över nästa rang, och rang 6 har tilldelats nästa post.
Precis som rank-funktionen kan dense_rank-funktionen också tillämpas på partition by-satsen. Titta på följande skript:
SELECT Name,Make,Model, Price, Type, DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank FROM Car
Utdata från skriptet ovan ser ut så här:
3. Row_Number Funktion
Funktionen radnummer rangordnar också posterna enligt de villkor som anges av ORDER BY-satsen. Men till skillnad från funktionerna rank och dense_rank, tilldelar row_number-funktionen inte samma rankning där det finns dubbletter av värden för kolumnen som anges av ORDER BY-satsen. Titta på följande skript:
SELECT Name,Make,Model, Price, Type, DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank FROM Car
Utdata från skriptet ovan ser ut så här:
Från skriptet ovan kan du se att både 5:e och 6:e posterna har samma värde för kolumnen Pris, men rangordningen som tilldelats dem är annorlunda.
På liknande sätt kan funktionen radnummer tillämpas på den partitionerade datan. Titta på följande skript till exempel.
SELECT Name,Make,Model, Price, Type, ROW_NUMBER() OVER(PARTITION BY Type ORDER BY Price DESC) AS PriceRankRow FROM Car
Utdata från skriptet ovan ser ut så här:
4. NTILE-funktion
NTILE-funktionen grupperar rankningen. Anta att du har 12 poster i en tabell och du vill rangordna dem i grupper om 4. De tre första posterna kommer att ha rang 1, de nästa tre posterna kommer att ha rang 2 och så vidare.
Låt oss ta en titt på ett exempel på NTILE-funktionen.
Use Showroom SELECT Name,Make,Model, Price, Type, NTILE(4) OVER(ORDER BY Price DESC) as NtilePrice FROM Car
I skriptet ovan skickade vi 4 som en parameter till NTILE-funktionen. Eftersom vi har 12 poster kommer du att se totalt 4 olika rankningar där 1 rank kommer att tilldelas tre poster. Utdatan ser ut så här:
Du kan se att de första tre dyraste bilarna har rankats 1, de kommande tre har rankats 2 och så vidare.
NTILE-funktionen kan också tillämpas på den partitionerade datan. Titta på följande skript:
SELECT Name,Make,Model, Price, Type, NTILE(4) OVER(PARTITION BY Type ORDER BY Price DESC) as NtilePrice FROM Car
Slutsats
Rankningsfunktioner i SQL Server används för att rangordna data på olika sätt. I denna läsning introducerade vi olika typer av rankningsfunktioner med exemplen. Funktionerna rank och dense_rank ger samma rankning till data med samma värden i ORDER BY-satsen medan row_number-funktionen rankar posten stegvis även om det är oavgjort.
Om inga dubbletter av poster finns i den angivna kolumnen genom ORDER BY-satsen, fungerar funktionerna rank, dense_rank och row_number på liknande sätt.