Předpokládejme, že navrhujete databázovou aplikaci SQL Server pro generálního ředitele společnosti a musíte zobrazit pátého nejlépe placeného zaměstnance ve společnosti.
Co bys dělal? Jedním z řešení je napsat dotaz takto:
SELECT EmployeeName FROM Employees ORDER BY Salary DESC OFFSET 4 ROWS FETCH FIRST 1 ROWS ONLY;
Výše uvedený dotaz vypadá těžkopádně, zvláště pokud musíte seřadit všechny zaměstnance. V takovém případě je jedním z řešení seřadit zaměstnance sestupně podle platu a poté vzít jako hodnost index zaměstnance. Věci se však zkomplikují, pokud má více zaměstnanců stejný plat. Jak byste je seřadili?
Naštěstí SQL Server přichází s vestavěnými funkcemi hodnocení, které lze použít k hodnocení záznamů různými způsoby. V tomto článku si podrobně představíme funkce hodnocení SQL serveru a ilustrujeme to na příkladech.
SQL Server má čtyři různé typy funkcí hodnocení:
- Pořadí()
- Dense_Rank()
- Číslo řádku()
- Ntile()
Je důležité zmínit, že všechny hodnotící funkce na SQL serveru vyžadují klauzuli ORDER BY.
Než se podrobně podíváme na každou z hodnoticích funkcí, nejprve si vytvořte fiktivní data, která budeme v tomto článku používat k vysvětlení funkce hodnocení. Spusťte následující 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')
Ve výše uvedeném skriptu vytvoříme databázi Showroom s jednou tabulkou Car. Tabulka Car má pět atributů:CarId, Name, Make, Model, Price a Type.
Dále jsme přidali 12 fiktivních záznamů do tabulky Car.
Nyní vidíte každou funkci hodnocení.
1. Funkce hodnocení
Funkce hodnocení na serveru SQL přiřazuje každému záznamu pořadí podle klauzule ORDER BY. Pokud například chcete vidět páté nejdražší auto v tabulce Car, můžete použít funkci hodnocení takto:
Use Showroom SELECT Name,Make,Model, Price, Type, RANK() OVER(ORDER BY Price DESC) as PriceRank FROM Car
Ve výše uvedeném skriptu vyberte název, značku, model, cenu, typ a hodnocení každého vozu seřazeného podle ceny ve sloupci „Cena“. Syntaxe funkce Rank je jednoduchá. Musíte napsat funkci RANK následovanou operátorem OVER. Uvnitř operátoru OVER musíte předat klauzuli ORDER BY, která třídí data. Výstup výše uvedeného skriptu vypadá takto:
U každého vozu můžete vidět pořadí. Je důležité zmínit, že pokud je nerozhodný výsledek mezi dvěma rekordy, další pozice v žebříčku je přeskočena. Například existuje shoda mezi záznamem 5 a 6 ve výstupu. Parado i Civic mají stejné ceny, a proto se umístily na 5. Nicméně další pořadí, konkrétně 6. místo, je přeskočeno a další dva vozy v seznamu jsou na 7. místě, protože mají také stejnou cenu. Po 7. pozici je pozice 8 znovu přeskočena a další přiřazená pozice je 9.
Data můžete rozdělit do oddílů a poté na jednotlivé oddíly použít hodnocení. V následujícím skriptu je rozdělení záznamů podle typu. Auta řadíme do každého oddílu.
SELECT Name,Make,Model, Price, Type, RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as PriceRank FROM Car
Výstup výše uvedeného skriptu vypadá takto:
Z výstupu je patrné, že záznamy byly rozděleny podle typů vozů a hodnost byla přidělena lokálně uvnitř oddílu. Například první dva záznamy patří do oddílu „Hatchback“ a byly zařazeny na 1 a 2. U dalšího oddílu, tj. „Sedan“, je pořadí resetováno na 1.
2. Funkce Dense_Rank
Funkce dense_rank je podobná funkci rank. Pokud však v případě hustoty_rank existuje shoda mezi dvěma záznamy z hlediska pořadí, další pořadí se nepřeskočí. Pojďme si to ukázat na příkladu. Spusťte následující skript:
Use Showroom SELECT Name,Make,Model, Price, Type, DENSE_RANK() OVER(ORDER BY Price DESC) as DensePriceRank FROM Car
Opět můžete vidět, že 5. a 6. záznam má stejnou hodnotu pro cenu a oběma bylo přiřazeno pořadí 5. Avšak na rozdíl od funkce hodnocení, která přeskočila další pořadí, funkce dense_rank nepřeskočí další pořadí a pořadí 6 byl přiřazen k dalšímu záznamu.
Stejně jako funkci rank lze funkci dense_rank také použít na oddíl podle klauzule. Podívejte se na následující skript:
SELECT Name,Make,Model, Price, Type, DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank FROM Car
Výstup výše uvedeného skriptu vypadá takto:
3. Funkce číslo_řádku
Funkce číslo_řádku také řadí záznamy podle podmínek specifikovaných klauzulí ORDER BY. Na rozdíl od funkcí rank a dense_rank však funkce row_number nepřiřazuje stejné hodnocení tam, kde existují duplicitní hodnoty pro sloupec určený klauzulí ORDER BY. Podívejte se na následující skript:
SELECT Name,Make,Model, Price, Type, DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank FROM Car
Výstup výše uvedeného skriptu vypadá takto:
Z výše uvedeného skriptu můžete vidět, že 5. i 6. záznam mají stejnou hodnotu ve sloupci Cena, ale jejich přiřazení je odlišné.
Podobně lze funkci row_number použít na rozdělená data. Podívejte se například na následující skript.
SELECT Name,Make,Model, Price, Type, ROW_NUMBER() OVER(PARTITION BY Type ORDER BY Price DESC) AS PriceRankRow FROM Car
Výstup výše uvedeného skriptu vypadá takto:
4. Funkce NTILE
Funkce NTILE seskupuje hodnocení. Předpokládejme, že máte v tabulce 12 záznamů a chcete je seřadit do skupin po 4. První tři záznamy budou mít hodnost 1, další tři záznamy budou mít hodnost 2 a tak dále.
Podívejme se na příklad funkce NTILE.
Use Showroom SELECT Name,Make,Model, Price, Type, NTILE(4) OVER(ORDER BY Price DESC) as NtilePrice FROM Car
Ve výše uvedeném skriptu jsme předali 4 jako parametr funkci NTILE. Protože máme 12 záznamů, uvidíte celkem 4 různé hodnosti, kde 1 hodnost bude přiřazena třem záznamům. Výstup vypadá takto:
Můžete vidět, že první tři nejdražší vozy byly zařazeny na 1., další tři na 2. a tak dále.
Funkci NTILE lze také použít na rozdělená data. Podívejte se na následující skript:
SELECT Name,Make,Model, Price, Type, NTILE(4) OVER(PARTITION BY Type ORDER BY Price DESC) as NtilePrice FROM Car
Závěr
Funkce hodnocení v SQL Server se používají k hodnocení dat různými způsoby. V tomto čtení jsme s příklady představili různé typy hodnotících funkcí. Funkce rank a dense_rank dávají stejnou hodnotu datům se stejnými hodnotami v klauzuli ORDER BY, zatímco funkce row_number řadí záznam přírůstkovým způsobem, i když existuje shoda.
V případě, že v zadaném sloupci nejsou žádné duplicitní záznamy pomocí klauzule ORDER BY se funkce rank, dense_rank a row_number chovají podobným způsobem.