Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Функции за класиране в SQL Server

Да предположим, че проектирате приложение за база данни на SQL Server за главен изпълнителен директор на компанията и трябва да покажете петия най-високоплатен служител в компанията.

Какво би направил? Едно решение е да напишете заявка като тази:

SELECT EmployeeName
FROM Employees
ORDER BY Salary DESC
OFFSET 4 ROWS
FETCH FIRST 1 ROWS ONLY;

Заявката по-горе изглежда тромава, особено ако трябва да класирате всички служители. В този случай едно решение е да изброите служителите по низходящ ред на заплатата и след това да вземете индекса на служителя като ранг. Нещата обаче се усложняват, ако множеството служители имат една и съща заплата. Как бихте ги класирали?

За щастие SQL Server идва с вградени функции за класиране, които могат да се използват за класиране на записи по различни начини. В тази статия ще представим функциите за класиране на SQL сървъри в подробности, илюстрирайки го с примерите.

Има четири различни типа функции за класиране в SQL Server:

  • Ранг()
  • Dense_Rank()
  • Номер на ред()
  • Ntile()

Важно е да се спомене, че всички функции за класиране в SQL сървър изискват клаузата ORDER BY.

Преди да разгледаме подробно всяка от функциите за класиране, първо, нека създадем фиктивни данни, които ще използваме в тази статия, за да обясним функцията за класиране. Изпълнете следния скрипт:

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')

В скрипта по-горе създаваме база данни на Showroom с една маса Car. Таблицата Car има пет атрибута:CarId, Име, Марка, Модел, Цена и Тип.

След това добавихме 12 фиктивни записа в таблицата Car.

Сега виждате всяка от функциите за класиране.

1. Функция за ранг

Функцията за ранг в SQL сървъра присвоява ранг на всеки запис, подреден от клаузата ORDER BY. Например, ако искате да видите петата най-скъпа кола в таблицата Car, можете да използвате функцията за ранг, както следва:

Use Showroom
SELECT Name,Make,Model, Price, Type,
RANK() OVER(ORDER BY Price DESC) as PriceRank
FROM Car

В скрипта по-горе изберете Име, Марка, Модел, Цена, Тип и ранга на всяка кола, подредена по Цена, като колона „PriceRank“. Синтаксисът за функцията Rank е прост. Трябва да напишете функцията RANK, последвана от оператора OVER. Вътре в оператора OVER трябва да предадете клаузата ORDER BY, която сортира данните. Резултатът от скрипта по-горе изглежда така:

Можете да видите ранга за всяка кола. Важно е да се спомене, че ако има равенство между ранговете на два рекорда, следващата позиция в класирането се пропуска. Например, има връзка между запис 5 и 6 в изхода. И Parado, и Civic имат равни цени и следователно са класирани на 5. Следващият ранг обаче, по-специално ранг 6, е пропуснат и следващите две коли в списъка са класирани на 7, тъй като те също имат една и съща цена. След 7-ми ранг, ранг 8 се пропуска отново и следващият присвоен ранг е 9.

Можете да разделите данните на дялове и след това да приложите класиране към отделни дялове. В следващия скрипт има разделяне на записите по тип. Класираме колите във всеки дял.

SELECT Name,Make,Model, Price, Type,
RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as PriceRank
FROM Car

Резултатът от скрипта по-горе изглежда така:

От изхода е видно, че записите са разделени по видове автомобили и рангът е присвоен локално вътре в дяла. Например, първите два записа принадлежат на дял „Хечбек“ и са класирани на 1 и 2. За следващия дял, т.е. „Седан“, рангът се нулира на 1.

2. Функция Dense_Rank

Функцията dense_rank е подобна на функцията за ранг. Въпреки това, в случай на dense_rank, ако има равенство между два записа по отношение на ранга, следващият ранг не се пропуска. Нека видим да го демонстрираме с примера. Изпълнете следния скрипт:

Use Showroom
SELECT Name,Make,Model, Price, Type,
DENSE_RANK() OVER(ORDER BY Price DESC) as DensePriceRank
FROM Car

Отново можете да видите, че 5-ти и 6-ти запис имат една и съща стойност за Price и и на двата им е присвоен ранг 5. Въпреки това, за разлика от функцията за ранг, която е пропуснала следващия ранг, функцията dense_rank не пропуска следващия ранг, а ранга 6 е присвоен към следващия запис.

Подобно на функцията за ранг, функцията dense_rank също може да бъде приложена към разделянето по клауза. Вижте следния скрипт:

SELECT Name,Make,Model, Price, Type,
DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank
FROM Car

Резултатът от скрипта по-горе изглежда така:

3. Функция номер_ред

Функцията row_number също така класира записите според условията, посочени от клаузата ORDER BY. Въпреки това, за разлика от функциите rank и dense_rank, функцията row_number не присвоява същия ранг, когато има дублиращи се стойности за колоната, определена от клаузата ORDER BY. Вижте следния скрипт:

SELECT Name,Make,Model, Price, Type,
DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank
FROM Car

Резултатът от скрипта по-горе изглежда така:

От скрипта по-горе можете да видите, че и 5-ият, и 6-ият запис имат една и съща стойност за колона Цена, но рангът, присвоен им е различен.

По подобен начин функцията row_number може да се приложи към разделените данни. Вижте например следния скрипт.

SELECT Name,Make,Model, Price, Type,
ROW_NUMBER() OVER(PARTITION BY Type ORDER BY Price DESC) AS PriceRankRow
FROM Car

Резултатът от скрипта по-горе изглежда така:

4. NTILE функция

Функцията NTILE групира класирането. Да предположим, че имате 12 записа в таблица и искате да ги класирате в групи от по 4. Първите три записа ще имат ранг 1, следващите три записа ще имат ранг 2 и така нататък.

Нека да разгледаме пример за функцията NTILE.

Use Showroom
SELECT Name,Make,Model, Price, Type,
NTILE(4) OVER(ORDER BY Price DESC) as NtilePrice
FROM Car

В горния скрипт предадохме 4 като параметър на функцията NTILE. Тъй като имаме 12 записа, ще видите общо 4 различни ранга, където 1 ранг ще бъде присвоен на три записа. Резултатът изглежда така:

Можете да видите, че първите три най-скъпи коли са класирани на 1, следващите три са на 2 и така нататък.

Функцията NTILE може да се приложи и към разделените данни. Вижте следния скрипт:

SELECT Name,Make,Model, Price, Type,
NTILE(4) OVER(PARTITION BY Type ORDER BY Price DESC) as NtilePrice
FROM Car

Заключение

Функциите за класиране в SQL Server се използват за класиране на данни по различни начини. В това четиво ние представихме различни видове функции за класиране с примерите. Функциите rank и dense_rank дават един и същ ранг на данните със същите стойности в клаузата ORDER BY, докато функцията row_number класира записа по нарастващ начин, дори ако има равенство.
В случай на липса на дублиращи се записи в посочената колона от клаузата ORDER BY функциите за ранг, dense_rank и row_number се държат по подобен начин.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Конкатна стойност на полето към низ в SQL Server

  2. SQL Server Промяна на името на базата данни

  3. Как да получите време от формат DateTime в SQL?

  4. Как SHOWPLAN_XML работи в SQL Server

  5. LEFT() срещу SET TEXTSIZE в SQL Server:Каква е разликата?