понедельник, 4 апреля 2011 г.

Третий сверху

Задали стандартный вопросик по SQL Server: "Как найти сотрудника с самой высокой зарплатой?" Ну, это понятно - SELECT TOP 1 emp_id FROM salary ORDER BY salary DESC.

Следующий вопрос немного посложнее: "Найти сотрудника с третьей по величине зарплатой". Я это написал, как обычно, с использованием функции ROW_NUMBER(): отсортировал по убыванию зарплаты, в подзапросе пронумеровал строки, а потом отфильтровал по номеру.

А оказывается, есть более изящное решение: отфильтровать по убыванию, взять трех самых высокооплачиваемых сотрудников, а потом их "перевернуть" (отфильтровать по возрастанию зарплаты и взять самого первого):

SELECT TOP 1 emp_id
FROM
(
SELECT TOP 3 emp_id, salary
FROM salary
ORDER BY salary DESC
) top3
ORDER BY salary

Не уверен, правда, что это работает быстрее моего решения. Очень может быть, что одинаково - у SQL Server 2008 R2 хороший оптимизатор...

5 комментариев:

velvet_shadow комментирует...

А если в наборе данных 5 сотрудников с самой высокой зарплатой? То выберется один из этих сотрудников, и его зарплата не будет третьей по величине. Причем как при первом подходе, так и втором.

Valik комментирует...

Ну да, я в курсе про WITH TIES. Подразумевалось, что зарплаты у всех разные.

Z комментирует...

А ещё есть функция rank(), но я бы оторвал руки тому кто её будет использовать.. ибо раскуривать потом такой код крайне тяжело.
И вообще, это конечно круто так спросить - третья по величине зарплата, но реально в жизни я ещё не встречал задач где нужно выполнять подобные запросы.

oleg_rod комментирует...

>Z
Пример задачи для rank():
нужно сделать уникальное ключевое поле по набору полей

Bashir Magomedov комментирует...

Хех :) Меня тоже самое спрашивали.

Ratings by outbrain