Antag, at du designer en SQL Server-databaseapplikation til en virksomheds administrerende direktør, og du skal vise den femte bedst betalte medarbejder i virksomheden.
Hvad ville du gøre? En løsning er at skrive en forespørgsel som denne:
SELECT EmployeeName FROM Employees ORDER BY Salary DESC OFFSET 4 ROWS FETCH FIRST 1 ROWS ONLY;
Forespørgslen ovenfor ser besværlig ud, især hvis du skal rangere alle medarbejderne. I så fald er en løsning at liste medarbejderne efter faldende lønrækkefølge og derefter tage indekset for medarbejderen som rang. Det bliver dog kompliceret, hvis de flere ansatte har samme løn. Hvordan ville du rangere dem?
Heldigvis kommer SQL Server med indbyggede rangeringsfunktioner, der kan bruges til at rangere poster på en række forskellige måder. I denne artikel vil vi introducere SQL-serverrangeringsfunktioner i detaljer og illustrere det med eksemplerne.
Der er fire forskellige typer rangeringsfunktioner i SQL Server:
- Rank()
- Dense_Rank()
- Rækkenummer()
- Ntile()
Det er vigtigt at nævne, at alle rangeringsfunktioner i SQL-serveren kræver ORDER BY-klausulen.
Før vi ser nærmere på hver af rangeringsfunktionerne, lad os først oprette dummy-data, som vi vil bruge i denne artikel til at forklare rangeringsfunktionen. Udfør følgende script:
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 scriptet ovenfor opretter vi Showroom-database med ét bord Bil. Bil-tabellen har fem attributter:CarId, Name, Make, Model, Price og Type.
Dernæst tilføjede vi 12 dummy-records i Bil-tabellen.
Nu ser du hver af rangeringsfunktionerne.
1. Rangeringsfunktion
Rangeringsfunktionen i SQL-serveren tildeler rang til hver post sorteret efter ORDER BY-sætningen. For eksempel, hvis du vil se den femte dyreste bil i Bil-tabellen, kan du bruge rangfunktionen som følger:
Use Showroom SELECT Name,Make,Model, Price, Type, RANK() OVER(ORDER BY Price DESC) as PriceRank FROM Car
I scriptet ovenfor skal du vælge navn, mærke, model, pris, type og rangeringen af hver bil sorteret efter pris som "PriceRank"-kolonnen. Syntaksen for Rank-funktionen er enkel. Du skal skrive funktionen RANK efterfulgt af OVER-operatoren. Inde i OVER-operatoren skal du videregive ORDER BY-klausulen, der sorterer dataene. Outputtet af scriptet ovenfor ser sådan ud:
Du kan se rangeringen for hver bil. Det er vigtigt at nævne, at hvis der er uafgjort mellem rækkerne af to rekorder, springes den næste ranglisteposition over. For eksempel er der uafgjort mellem post 5 og 6 i outputtet. Både Parado og Civic har lige priser, og er derfor blevet rangeret 5. Men den næste placering, især rank 6 er sprunget over, og de næste to biler på listen er blevet rangeret 7, da de også har samme pris. Efter den 7. rang, springes rang 8 over igen, og den næste tildelte rang er 9.
Du kan opdele dataene i partitioner og derefter anvende rangering på individuelle partitioner. I det følgende script er der opdelingen af posterne efter type. Vi rangerer bilerne inde i hver skillevæg.
SELECT Name,Make,Model, Price, Type, RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as PriceRank FROM Car
Outputtet af scriptet ovenfor ser sådan ud:
Det fremgår af outputtet, at posterne er blevet opdelt efter biltyper, og rangeringen er blevet tildelt lokalt inde i partitionen. For eksempel tilhører de to første poster partitionen "Hatchback" og er blevet rangeret 1 og 2. For den næste partition, dvs. "Sedan", nulstilles rangeringen til 1.
2. Dense_Rank-funktion
Dense_rank-funktionen svarer til rank-funktionen. Men i tilfælde af dense_rank, hvis der er uafgjort mellem to poster med hensyn til rang, springes den næste rang ikke over. Lad os se demonstrere det med eksemplet. Udfør følgende script:
Use Showroom SELECT Name,Make,Model, Price, Type, DENSE_RANK() OVER(ORDER BY Price DESC) as DensePriceRank FROM Car
Igen kan du se, at den 5. og 6. post har samme værdi for Price, og begge er blevet tildelt rang 5. Men i modsætning til rangfunktion, der sprang over den næste rang, springer dense_rank-funktionen ikke over den næste rang, og rang 6 er blevet tildelt den næste post.
Ligesom rank-funktionen kan dense_rank-funktionen også anvendes på partition by-klausulen. Se på følgende script:
SELECT Name,Make,Model, Price, Type, DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank FROM Car
Outputtet af scriptet ovenfor ser sådan ud:
3. Rækkenummer-funktion
Funktionen rækkenummer rangerer også posterne i henhold til betingelserne specificeret af ORDER BY-udtrykket. Men i modsætning til funktionerne rank og dense_rank, tildeler row_number-funktionen ikke samme rang, hvor der er duplikerede værdier for kolonnen angivet af ORDER BY-sætningen. Se på følgende script:
SELECT Name,Make,Model, Price, Type, DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank FROM Car
Outputtet af scriptet ovenfor ser sådan ud:
Fra scriptet ovenfor kan du se, at både 5. og 6. post har samme værdi for kolonnen Pris, men den rangering, der er tildelt dem, er forskellig.
På samme måde kan rækkenummer-funktionen anvendes på de partitionerede data. Se for eksempel på følgende script.
SELECT Name,Make,Model, Price, Type, ROW_NUMBER() OVER(PARTITION BY Type ORDER BY Price DESC) AS PriceRankRow FROM Car
Outputtet af scriptet ovenfor ser sådan ud:
4. NTILE-funktion
NTILE-funktionen grupperer rangeringen. Antag, at du har 12 poster i en tabel, og du vil rangere dem i grupper af 4. De første tre poster vil have rang 1, de næste tre poster vil have rang 2 og så videre.
Lad os tage et kig på et eksempel på NTILE-funktionen.
Use Showroom SELECT Name,Make,Model, Price, Type, NTILE(4) OVER(ORDER BY Price DESC) as NtilePrice FROM Car
I ovenstående script sendte vi 4 som en parameter til NTILE-funktionen. Da vi har 12 poster, vil du se i alt 4 forskellige ranger, hvor 1 rang vil blive tildelt tre poster. Outputtet ser sådan ud:
Du kan se, at de første tre dyreste biler er blevet rangeret 1, de næste tre er blevet rangeret 2 og så videre.
NTILE-funktionen kan også anvendes på de partitionerede data. Se på følgende script:
SELECT Name,Make,Model, Price, Type, NTILE(4) OVER(PARTITION BY Type ORDER BY Price DESC) as NtilePrice FROM Car
Konklusion
Rangeringsfunktioner i SQL Server bruges til at rangere data på forskellige måder. I denne læsning introducerede vi forskellige typer rangeringsfunktioner med eksemplerne. Funktionerne rank og dense_rank giver samme rang til dataene med samme værdier i ORDER BY-sætningen, hvorimod row_number-funktionen rangerer posten trinvist, selvom der er uafgjort.
I tilfælde af ingen duplikerede poster i den angivne kolonne ved ORDER BY-sætningen opfører funktionerne rank, dense_rank og row_number sig på samme måde.