2013-03-18 5 views
0

У меня есть таблица; содержащий 2 поля, имя и заработную плату. Я использовал ниже сценарий, чтобы найти 3-ей максимальную зарплату.N-й запрос максимальной зарплаты в SQL

SELECT DISTINCT sal 
FROM downtodate1.emp e1 
WHERE 3 = (SELECT COUNT(DISTINCT sal) FROM downtodate1.emp e2 WHERE e1.sal<= e2.sal); 

Я хочу знать, как это работает и почему 3 используется здесь?

+0

Вы фильтруете для r ecords ", где 3 - количество отчетливых окладов, к которым текущая зарплата меньше или равна". То есть, когда есть 3 отличных зарплаты, которые больше или равны текущей записи; помните, что текущая запись сама по себе является одной из этих трех. – eggyal

ответ

0

Вместо этого вы можете использовать это, чтобы найти NTH Макс зарплату

SELECT sal FROM emp 
ORDER BY sal DESC 
LIMIT N,1 

N быть Nth номер.

+0

thanks.It будет работать, но мне интересно узнать механизм запроса, который я задал. – Suri

+0

Нет, это не работает. У вас есть зарплаты 3, 3, 2, 1, 1, 0 в вашем столе. С результатом вашего запроса будет 2, тогда как результат должен быть равен 1, так как зарплаты равны. – fancyPants

+0

@tombom да получил. – Suri

0

Возможно переформатирование запрос будет уточнить:

select distinct sal 
from downtodate1.emp AS e1 
where 3 = (
    select count(distinct sal) 
    from downtodate1.emp e2 
    where e1.sal <= e2.sal 
); 

В результате подзапроса сравниваются с 3, так как количество предшествующих строк для requried строки. Это (потенциально) вычисление O (N^2), но в этом случае этого может быть достаточно.

+0

При вычислении временной сложности вы не предполагаете, что на 'downtodate1.emp.sal' нет индекса B-дерева? – eggyal

+0

Обновлено. Да, оптимизация может существовать, но нельзя предполагать, что они на месте. Count() обычно является неэффективной операцией, когда это не вся коллекция. –

+0

как 3 будет сравниваться с подзапросом. Можете ли вы объяснить подсубъект в этом случае? – Suri

1

Вот быстрый способ ...

SELECT salary 
    FROM 
     (
     SELECT salary 
      , @prev := @curr 
      , @curr := salary 
      , @rank := IF(@prev = @curr, @rank, @rank+1) rank 
      FROM employee 
     CROSS 
      JOIN 
      (SELECT @curr := null, @prev := null, @rank := 0) sel1 
     ORDER 
      BY salary DESC 
    ) x 
    WHERE rank = 3; 
1
select distinct sal 
from downtodate1.emp AS e1 
where 3 = (
    select count(distinct sal) 
    from downtodate1.emp e2 
    where e1.sal <= e2.sal 
); 

Рассмотрим у вас есть таблица вроде этого:

С этой части

select distinct sal 
from downtodate1.emp AS e1 

вы получите результат

sal 
--- 
3 
2 
1 
0 

Это составляет 4 отличных зарплаты.

Теперь подзапрос

select count(distinct sal) 
    from downtodate1.emp e2 
    where e1.sal <= e2.sal 

выполняется для каждой строки основного запроса. Он вычисляет количество различных значений, которые ниже или равны строке в основном запросе. Таким образом, результатом этого является фактически (но не отображается):

sal | count(distinct sal) where e1.sal <= e2.sal 
------------------------------------------------ 
3  1 
3  1 
2  2 
1  3 
1  3 
0  4 

С отличным от основного запроса вы получите этот результат:

sal | count(distinct sal) where e1.sal <= e2.sal 
------------------------------------------------ 
3  1 
2  2 
1  3 
0  4 

и с оговоркой WHERE3 = (/*subquery*/) вы будете получить только

sal | count(distinct sal) where e1.sal <= e2.sal 
------------------------------------------------ 
1  3 

этот номер. Таким образом, результат 1.

Надеюсь, теперь это ясно.

+0

считает дорогим. Я понял сейчас. – Suri

0

это-так же, как вы записаны

where 
(select count(distinct sal) from downtodate1.emp e2 where e1.sal <= e2.sal) = 3 ; 

, где а = 3

или где 3 = подсчет отчетливых продаж

0

Простой способ получить максимальную запись заработной платы работника с subQueries

select * from Employee where salary in (select max(salary) from Employee)

Смежные вопросы