Как найти третью или энную максимальную зарплату из таблицы зарплат?


98

Как найти third or nthмаксимальную зарплату из зарплаты table(EmpID,EmpName,EmpSalary)Оптимизированным способом?



1
SELECT salary FROM (SELECT salary FROM employee ORDER BY salary DESC FETCH NEXT 3 ROWS ONLY) ORDER BY salary ASC FETCH NEXT 1 ROWS ONLY;
Сатвик

Ответы:


83

Используйте ROW_NUMBER(если вы хотите одну) или DENSE_RANK(для всех связанных строк):

WITH CTE AS
(
    SELECT EmpID, EmpName, EmpSalary,
           RN = ROW_NUMBER() OVER (ORDER BY EmpSalary DESC)
    FROM dbo.Salary
)
SELECT EmpID, EmpName, EmpSalary
FROM CTE
WHERE RN = @NthRow

как получить минимальную зарплату из таблицы? выберите ins.KYS_ID, ins.FKYS_INS_ID из cmn_pat_x_insurance ins, где ins.FKYS_PAT_ID = '1253_717' и ins.FKYS_INS_TYPE в (1) и ins.BOL_TYPE в (1,3) и ins.salary в (min (ins.salary))
сайдеш Килару

Представьте, что в таблице сотрудников 10,0000 записей. Если я воспользуюсь вышеуказанным запросом, то производительность снизится в 6-10 раз.
Bimal Das

1
@BimalDas: тогда у вас нет индекса в EmpSalaryстолбце. Кроме того, уменьшено по сравнению с чем? Преимущество такого ROW_NUMBERподхода в том, что его можно использовать ..OVER(PARTITION BY GroupColumn OrderBy OrderColumn). Таким образом, вы можете использовать его для получения групп, но при этом получить доступ к любому его столбцу.
Тим

@TimSchmelter WITH CTE создаст временную таблицу для хранения в ней всех данных первого оператора SELECT, а затем из результата мы выберем «SELECT EmpID, EmpName, EmpSalary FROM CTE WHERE RN = @NthRow». Поэтому я думаю, что это немного медленно. Я проверил это. и у меня тоже есть правильная индексация.
Bimal Das

2
@BimalDas: Нет, временная таблица не создается. Cte обычно нигде не материализуется. Это больше похоже на встроенное представление или именованный подзапрос.
Тим

89

Номер строки:

SELECT Salary,EmpName
FROM
  (
   SELECT Salary,EmpName,ROW_NUMBER() OVER(ORDER BY Salary) As RowNum
   FROM EMPLOYEE
   ) As A
WHERE A.RowNum IN (2,3)

Подзапрос:

SELECT *
FROM Employee Emp1
WHERE (N-1) = (
               SELECT COUNT(DISTINCT(Emp2.Salary))
               FROM Employee Emp2
               WHERE Emp2.Salary > Emp1.Salary
               )

Верхнее ключевое слово:

SELECT TOP 1 salary
FROM (
      SELECT DISTINCT TOP n salary
      FROM employee
      ORDER BY salary DESC
      ) a
ORDER BY salary

как получить минимальную зарплату из таблицы? выберите ins.KYS_ID, ins.FKYS_INS_ID из cmn_pat_x_insurance ins, где ins.FKYS_PAT_ID = '1253_717' и ins.FKYS_INS_TYPE в (1) и ins.BOL_TYPE в (1,3) и ins.salary в (min (ins.salary))
сайдеш Килару

Кумар и Александр, я хочу получить еще одно поле, как это сделать? мой запрос похож на "" "Выбрать Top 1 NoteID из (Select DateDiff (Year, SchedualDate, Current_TimeStamp) как NoteAge, Distinct Top 3 NoteID From [dbo]. [DocSecheduale] Order by NoteID Desc) Порядок по NoteID" ""
Zaveed Abbasi

Я нахожу n-ю самую высокую зарплату, но мне сложно понять подзапрос, не могли бы вы объяснить подзапрос ...
Дипак Гупта

@deepak_java подзапрос оценивается каждый раз, когда строка обрабатывается внешним запросом. Другими словами, внутренний запрос не может быть обработан независимо от внешнего запроса, поскольку внутренний запрос также использует значение Emp1.
Кумар Маниш,

Важно понять, почему это ... WHERE (N-1) = (Subquery)...работает. Подзапрос является коррелированным запросом, поскольку его WHEREпредложение использует Emp1из основного запроса. Подзапрос оценивается каждый раз, когда основной запрос просматривает строку. Например, если мы должны найти 3-ю по величине зарплату (N = 3) из (800, 1000, 700, 750), подзапрос для 1-й строки будет SELECT COUNT(DISTINCT(Emp2.Salary)) FROM Employee Emp2 WHERE Emp2.Salary > 800равен 0. Для 4-го значения зарплаты (750) ... WHERE Emp2.Salary > 750будет 2 или N -1, следовательно, эта строка будет возвращена.
jerrymouse

66

Попробуй это

SELECT TOP 1 salary FROM (
   SELECT TOP 3 salary 
   FROM employees 
   ORDER BY salary DESC) AS emp 
ORDER BY salary ASC

На 3 можно заменить любое значение ...


это работает с Oracle 10g или 11g? Или есть альтернатива, которая выглядит примерно так?
RBz

42

Если вы хотите оптимизировать способ, используйте TOP ключевое слово. Таким образом, n-й запрос максимальной и минимальной зарплаты выглядит следующим образом, но запросы выглядят сложными, как в обратном порядке, с использованием имен агрегированных функций:

Максимальная зарплата N:

SELECT MIN(EmpSalary)
FROM Salary
WHERE EmpSalary IN(SELECT TOP N EmpSalary FROM Salary ORDER BY EmpSalary DESC) 

Например: 3 максимальная зарплата:

SELECT MIN(EmpSalary)
FROM Salary
WHERE EmpSalary IN(SELECT TOP 3 EmpSalary FROM Salary ORDER BY EmpSalary DESC) 

N минимальная заработная плата:

SELECT MAX(EmpSalary)
FROM Salary
WHERE EmpSalary IN(SELECT TOP N EmpSalary FROM Salary ORDER BY EmpSalary ASC)

Например: 3 минимальная зарплата:

SELECT MAX(EmpSalary)
FROM Salary
WHERE EmpSalary IN(SELECT TOP 3 EmpSalary FROM Salary ORDER BY EmpSalary ASC)

Самый простой и легкий для запоминания. +1
Sнаđошƒаӽ

4
Чтобы получить максимальную зарплату, почему мы делаем это в порядке ASC, это нужно делать в порядке DESC, если у нас есть зарплата, такая как эта 7000,10000,11000,500,800,900,12000, тогда внутренний запрос сортировки приведет к top3, что означает 500,800,900 и максимум из них 900, но 900 - это не максимум 3, максимальная зарплата 3 - 10 000.
Нарендра Джагги

1
Например: 3 максимальных зарплаты: это должно быть так: ВЫБЕРИТЕ Min (EmpSalary) FROM Salary, WHERE EmpSalary IN (ВЫБЕРИТЕ ТОП 3 EmpSalary ИЗ ЗАПРОСА зарплаты BY EmpSalary DESC)
Джимит Рупани

15

Слишком просто, если использовать подзапрос!

SELECT MIN(EmpSalary) from (
SELECT EmpSalary from Employee ORDER BY EmpSalary DESC LIMIT 3
);

Здесь вы можете просто изменить n-е значение после ограничения LIMIT.

Здесь в этом подзапросе Выберите EmpSalary из заказа сотрудника с помощью EmpSalary DESC Limit 3; вернет 3 верхних зарплаты Сотрудников. Из результата мы выберем Минимальную зарплату с помощью команды MIN, чтобы получить 3-ю ТОП-зарплату сотрудника.


Получение этой ошибки. Код ошибки: 1248 У каждой производной таблицы должен быть собственный псевдоним

добавьте к нему псевдоним .. SELECT MIN (EmpSalary) из (SELECT EmpSalary from Employee ORDER BY EmpSalary DESC LIMIT 3) as s;
anonxss

Просто используйте DISTINCT, чтобы избежать дублирования SELECT MIN (EmpSalary) из (SELECT DISTINCT (EmpSalary) from Employee ORDER BY EmpSalary DESC LIMIT 3);
Kalpesh Parikh

14

Замените N своим максимальным числом

SELECT *
FROM Employee Emp1
WHERE (N-1) = (
SELECT COUNT(DISTINCT(Emp2.Salary))
FROM Employee Emp2
WHERE Emp2.Salary > Emp1.Salary)

Объяснение

Вышеупомянутый запрос может сбивать с толку, если вы раньше не видели ничего подобного - внутренний запрос - это то, что называется коррелированным подзапросом, потому что внутренний запрос (подзапрос) использует значение из внешнего запроса (в данном случае таблица Emp1 ) в предложении WHERE.

И Источник


+1 Важно понять, почему ... WHERE (N-1) = (Subquery)...работает. Подзапрос является коррелированным запросом, поскольку его WHEREпредложение использует Emp1из основного запроса. Подзапрос оценивается каждый раз, когда основной запрос просматривает строку. Например, если мы должны найти 3-ю по величине зарплату (N = 3) из (800, 1000, 700, 750), подзапрос для 1-й строки будет SELECT COUNT(DISTINCT(Emp2.Salary)) FROM Employee Emp2 WHERE Emp2.Salary > 800равен 0. Для 4-го значения зарплаты (750) ... WHERE Emp2.Salary > 750будет 2 или N -1, следовательно, эта строка будет возвращена.
jerrymouse

13

Третья или энная максимальная зарплата из таблицы зарплат без использования подзапроса

select salary from salary
   ORDER   BY salary DESC
   OFFSET  N-1 ROWS
   FETCH NEXT 1 ROWS ONLY

Для 3-й по величине зарплаты поставить 2 вместо N-1


3
Важно отметить, что OFFSET FETCH доступен в версии SQL Server 2012+.
Zerotoinfinity


8

Обратитесь к следующему запросу для получения n-й по величине зарплаты. Таким образом, вы получаете n-ю по высоте зарплату в MYSQL. Если вы хотите получить n-ю самую низкую зарплату, вам нужно заменить DESC на ASC в запросе. n-я по величине зарплата


1
Речь идет о SQL-сервере, а не о MySQL.
bummi


6

Способ 1:

SELECT TOP 1 salary FROM (
SELECT TOP 3 salary 
 FROM employees 
  ORDER BY salary DESC) AS emp 
 ORDER BY salary ASC

Способ 2:

  Select EmpName,salary from
  (
    select EmpName,salary ,Row_Number() over(order by salary desc) as rowid      
     from EmpTbl)
   as a where rowid=3

Метод 1 можно отсортировать: ВЫБЕРИТЕ ТОП-1 ЗАРПЛАТУ ИЗ (ВЫБЕРИТЕ ТОП-3 ЗАРПЛАТЫ ОТ СОТРУДНИКОВ) * причина - потому что по умолчанию ее порядок возрастания
Ашиш Агравал Йодли

5

В 2008 мы можем использовать ROW_NUMBER () OVER (ORDER BY EmpSalary DESC), чтобы получить ранг без связей, которые мы можем использовать.

Например, таким образом мы можем получить 8-е место или изменить @N на что-то другое или использовать его как параметр в функции, если хотите.

DECLARE @N INT = 8;
WITH rankedSalaries AS
(
SELECT
EmpID
,EmpName
,EmpSalary,
,RN = ROW_NUMBER() OVER (ORDER BY EmpSalary DESC)
FROM salary
)
SELECT
EmpID
,EmpName
,EmpSalary
FROM rankedSalaries
WHERE RN = @N;

В SQL Server 2012, как вы, возможно, знаете, это выполняется более интуитивно с помощью LAG ().



3

Это один из популярных вопросов в любом собеседовании по SQL. Я собираюсь записать разные запросы, чтобы узнать n-е наибольшее значение столбца.

Я создал таблицу с именем «Emloyee», выполнив приведенный ниже сценарий.

CREATE TABLE Employee([Eid] [float] NULL,[Ename] [nvarchar](255) NULL,[Basic_Sal] [float] NULL)

Теперь я собираюсь вставить 8 строк в эту таблицу, выполнив инструкцию вставки ниже.

insert into Employee values(1,'Neeraj',45000)
insert into Employee values(2,'Ankit',5000)
insert into Employee values(3,'Akshay',6000)
insert into Employee values(4,'Ramesh',7600)
insert into Employee values(5,'Vikas',4000)
insert into Employee values(7,'Neha',8500)
insert into Employee values(8,'Shivika',4500)
insert into Employee values(9,'Tarun',9500)

Теперь мы найдем 3-й по величине Basic_sal из приведенной выше таблицы, используя разные запросы. Я выполнил приведенный ниже запрос в студии управления, и ниже показан результат.

select * from Employee order by Basic_Sal desc

На изображении выше мы можем видеть, что 3-я по величине базовая зарплата будет 8500. Я пишу 3 разных способа сделать то же самое. Выполнив все три указанных ниже запроса, мы получим тот же результат, т.е. 8500.

Первый способ: - Использование функции номера строки

select Ename,Basic_sal
from(
            select Ename,Basic_Sal,ROW_NUMBER() over (order by Basic_Sal desc) as rowid from Employee
      )A
where rowid=2

3
Select TOP 1 Salary as '3rd Highest Salary' from (SELECT DISTINCT TOP 3 Salary from Employee ORDER BY Salary DESC) a ORDER BY Salary ASC;

У меня третья по величине зарплата



3

- самая высокая зарплата

select * 
from (select lstName, salary, row_number() over( order by salary desc) as rn 
      from employee) tmp
where rn = 2

- (n-е -1) самая высокая зарплата

select * 
from employee e1
where 1 = (select count(distinct salary)  
           from employee e2
           where e2.Salary > e1.Salary )



2

По подзапросу:

SELECT salary from
(SELECT rownum ID, EmpSalary salary from
(SELECT DISTINCT EmpSalary from salary_table order by EmpSalary DESC)
where ID = nth)

1

Попробуйте этот запрос

SELECT DISTINCT salary
FROM emp E WHERE
&no =(SELECT COUNT(DISTINCT salary) 
FROM emp WHERE E.salary <= salary)

Положите n = какое значение вы хотите



1

Решение, протестированное MySQL, предположим, что N = 4:

select min(CustomerID) from (SELECT distinct CustomerID FROM Customers order by CustomerID desc LIMIT 4) as A;

Другой пример:

select min(country) from (SELECT distinct country FROM Customers order by country desc limit 3);

1

Попробуйте этот код: -

SELECT *
   FROM one one1
   WHERE ( n ) = ( SELECT COUNT( one2.salary )
                   FROM one one2
                   WHERE one2.salary >= one1.salary
                 )

1

Найдите N-ую самую высокую зарплату из таблицы. Вот способ выполнить эту задачу с помощью функции density_rank ().

введите описание изображения здесь

select linkorder from u_links

select max(linkorder) from u_links

select max(linkorder) from u_links where linkorder < (select max(linkorder) from u_links)

select top 1 linkorder 
       from ( select distinct top 2 linkorder from u_links order by linkorder desc) tmp 
order by linkorder asc

DENSE_RANK: 1. DENSE_RANK вычисляет ранг строки в упорядоченной группе строк и возвращает ранг как ЧИСЛО. Ранги представляют собой последовательные целые числа, начинающиеся с 1. 2. Эта функция принимает аргументы как любой числовой тип данных и возвращает ЧИСЛО. 3. В качестве аналитической функции DENSE_RANK вычисляет ранг каждой строки, возвращаемой из запроса, по отношению к другим строкам на основе значений value_exprs в предложении order_by_clause. 4. В приведенном выше запросе ранг возвращается на основе sal таблицы сотрудников. В случае ничьи всем строкам присваивается одинаковый ранг.

WITH result AS ( 
     SELECT linkorder ,DENSE_RANK() OVER ( ORDER BY linkorder DESC ) AS  DanseRank 
FROM u_links ) 
SELECT TOP 1 linkorder FROM result WHERE DanseRank = 5

1

В SQL Server 2012+ эффективный способ добиться этого - OFFSET ... FETCH:

DECLARE @N AS INT;
SET @N = 3;

SELECT
    EmpSalary
FROM
    dbo.Salary
ORDER BY
    EmpSalary DESC
OFFSET (@N-1) ROWS
FETCH NEXT 1 ROWS ONLY

1
select * from employee order by salary desc;

+------+------+------+-----------+
| id   | name | age  | salary    |
+------+------+------+-----------+
|    5 | AJ   |   20 | 100000.00 |
|    4 | Ajay |   25 |  80000.00 |
|    2 | ASM  |   28 |  50000.00 |
|    3 | AM   |   22 |  50000.00 |
|    1 | AJ   |   24 |  30000.00 |
|    6 | Riu  |   20 |  20000.00 |
+------+------+------+-----------+




select distinct salary from employee e1 where (n) = (select count( distinct(salary) ) from employee e2 where e1.salary<=e2.salary);

Замените n номером n-й по величине зарплатой.


0
SELECT TOP 1 salary FROM ( SELECT TOP n salary FROM employees ORDER BY salary DESC Group By salary ) AS emp ORDER BY salary ASC

(где n - максимальная зарплата n)


0

Просто измените значение внутреннего запроса: например, Select Top (2) * from Student_Info order by ClassID desc

Используйте для обеих проблем:

Select Top (1)* from 
(
 Select Top (1)* from Student_Info order by ClassID desc 
) as wsdwe
order by ClassID 

0

Чтобы запросить nth highest bonus, скажем n=10, с помощью AdventureWorks2012, попробуйте следующий код

USE AdventureWorks2012; 
GO

SELECT * FROM Sales.SalesPerson;
GO

DECLARE @grade INT;
SET @grade = 10;
SELECT MIN(Bonus)
FROM (SELECT TOP (@grade) Bonus FROM (SELECT DISTINCT(Bonus) FROM Sales.SalesPerson) AS a ORDER BY Bonus DESC) AS g
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.