Команда SQL для поиска второй по величине зарплаты

Привет, Можете ли вы сказать мне синтаксис команды SQL, которая выводит вторую по величине зарплату из диапазона зарплат, хранящихся в таблице сотрудников. Описание команды SQL приветствуется... Пожалуйста, помогите!!!


person Smriti    schedule 28.11.2010    source источник
comment
возможный дубликат sql-запроса, чтобы найти n-ю самую высокую зарплату из зарплаты таблица   -  person LittleBobbyTables - Au Revoir    schedule 28.11.2010
comment
Другой вопрос и ответы на него относятся к SQL Server и т. Д. Так же, как и ответы здесь с TOP   -  person fredt    schedule 28.11.2010


Ответы (9)


Это должно работать:

select * from (
 select t.*, dense_rank() over (order by salary desc) rnk from employee t
) a 
where rnk = 2;

Возвращает вторую по величине зарплату.

dense_rank() over — это оконная функция, и она дает вам ранг определенной строки в указанном наборе. Это это стандартный SQL, определенный в SQL:2003.

Оконные функции в целом великолепны, они упрощают множество сложных запросов.

Немного другое решение:

Это идентично, за исключением того, что возвращает самую высокую зарплату, когда есть ничья для номера 1:

select * from (
 select t.*, row_number() over (order by salary desc) rnk from employee t
) a 
where rnk = 2;

Обновлено: ранг изменен на плотный_ранг и добавлено второе решение. Спасибо, ЯнК!

person Martin    schedule 28.11.2010
comment
Технически это единственный правильный ответ на этой странице (на момент, когда я его читал) и единственный гарантированный способ получить второй по величине результат. +1 - person IamIC; 28.11.2010
comment
На самом деле, @Martin, это должно быть плотное_rank(). rank() будет иметь пробелы, поэтому, если есть несколько одинаковых зарплат на позиции № 1, не будет результата rnk = 2. - person IamIC; 28.11.2010

with tempTable as(
    select top 2 max(salary) as MaxSalary from employee order by salary desc
) select top 1 MaxSalary from tempTable

описание:

  1. выберите 2 лучших максимальных зарплаты
  2. упорядочить их по убыванию (так что 2-я самая высокая зарплата теперь вверху)
  3. выберите 1 из них

другой подход:

select top 1 MaxSalary from (
    select top 2 max(salary) as MaxSalary from employee order by salary desc
)
person Ali Tarhini    schedule 28.11.2010
comment
Это не сработает. Функция max() вернет только 1 результат. - person IamIC; 28.11.2010
comment
Я проверил это... агрегатные функции возвращают только одну запись. :) - person IamIC; 28.11.2010
comment
@Ali, я тестировал это на SQL Server. SQL Server не будет выполнять агрегированную функцию без предложения have, которое я добавил. В этом контексте max ничего не делает, возвращая те же результаты, что и без него. Это связано с тем, что он применяет максимальное значение к каждой группе, как определено предложением have. Какие результаты вы получаете? - person IamIC; 28.11.2010
comment
Сказав все это, это будет работать (проверено): выберите Min (Salary) from ( выберите отдельную TOP (2) зарплату из @t as t в порядке DESC по зарплате) AS T - person IamIC; 28.11.2010

Вот пример кода с доказательством концепции:

declare @t table (
    Salary int
)

insert into @t values (100)
insert into @t values (900)
insert into @t values (900)
insert into @t values (400)
insert into @t values (300)
insert into @t values (200)

;WITH tbl AS (
    select t.Salary, DENSE_RANK() OVER (order by t.Salary DESC) AS Rnk
    from @t AS t
)
SELECT *
FROM tbl
WHERE Rnk = 2

DENSE_RANK является обязательным (измените на RANK, и вы увидите).

Вы также увидите, почему любые запросы SELECT TOP 2 не будут работать (во всяком случае, без DISTINCT).

person IamIC    schedule 28.11.2010

Вы не указываете фактический продукт SQL, который вы используете, и язык запросов зависит от продукта. Тем не менее, что-то вроде этого должно помочь вам начать:

SELECT salary FROM employees E1 
    WHERE 1 = (SELECT COUNT(*) FROM employee E2 WHERE E2.salary > E1.salary)

(спасибо Фредту за исправление).

В качестве альтернативы (и быстрее с точки зрения производительности) будет

SELECT TOP 2 salary FROM employees ORDER BY salary DESC

а затем пропустить первую возвращенную строку.

person Larry Lustig    schedule 28.11.2010
comment
Действительно так и сделал, спасибо за поправку. Я отредактирую оригинал. - person Larry Lustig; 28.11.2010
comment
Вам просто нужен отличный там :) - person IamIC; 28.11.2010

Альтернатива (проверено):

select Min(Salary) from (
    select distinct TOP (2) salary from employees order by salary DESC) AS T

Это будет работать на любой платформе, чисто и обеспечивает возможность нескольких связанных зарплат №1.

person IamIC    schedule 28.11.2010

Выберите 1 лучших * из сотрудников, где находится empID (выберите 2 лучших (empID) из заказа сотрудников по зарплате DESC) ORDER BY зарплата ASC

Объяснение:

выберите первые 2 (empID) из порядка сотрудников по зарплате. DESC даст две записи, для которых зарплата является верхней, а затем весь запрос отсортирует эти две записи в порядке ВОЗРАСТА, а затем перечислит ту, у которой самая низкая зарплата среди двух.

БЫВШИЙ. пусть зарплаты служащих равны 100, 99, 98, 50.

Запрос 1 вернет emp ID людей с sal 100 и 99.

Весь запрос вернет все данные, относящиеся к человеку с зарплатой 99.

person Jaykay    schedule 29.11.2010

 SELECT Salary,EmpName
 FROM
   (
   SELECT Salary,EmpName,ROW_NUMBER() OVER(ORDER BY Salary) As Rank
   FROM EMPLOYEE
   ) A
   WHERE A.Rank=n;

где n — номер самого высокого оклада ur, запрашивающего таблицу. Вы также можете использовать функцию DenseRank() вместо ROW_NUMBER().

Спасибо, Суреш

person suresh    schedule 15.12.2013

Более простой способ..

select MAX(salary) as SecondMax from test where salary !=(select MAX(salary) from test)
person Mitesh Vora    schedule 21.04.2014

person    schedule
comment
во внешнем запросе нет необходимости в минимальной (зарплате), потому что мы уже знаем, что вторая максимальная зарплата является верхней записью. поэтому выберите первую зарплату 1 достаточно, как в моем решении - person Ali Tarhini; 28.11.2010
comment
Использование LIMIT для реализаций, отличных от SQL Server. - person IamIC; 28.11.2010
comment
Вам нужно будет добавить DISTINCT в запрос или использовать разбиение Dense_Rank(), иначе нет гарантии, что вы получите правильный результат. - person IamIC; 28.11.2010
comment
На самом деле это можно обобщить не только на второй, но и на n-й сверху или снизу зарплаты. - person pranjal; 16.12.2010