Найдите вторую по величине зарплату

Ну, это известный вопрос. Рассмотрим ниже

EmployeeID  EmployeeName    Department      Salary   
----------- --------------- --------------- ---------
1           T Cook          Finance         40000.00
2           D Michael       Finance         25000.00
3           A Smith         Finance         25000.00
4           D Adams         Finance         15000.00
5           M Williams      IT              80000.00
6           D Jones         IT              40000.00
7           J Miller        IT              50000.00
8           L Lewis         IT              50000.00
9           A Anderson      Back-Office     25000.00
10          S Martin        Back-Office     15000.00
11          J Garcia        Back-Office     15000.00
12          T Clerk         Back-Office     10000.00

Нам нужно узнать вторую по величине зарплату

With Cte As
(
  Select 
    level
    ,Department
    ,Max(Salary) 
 From plc2_employees
 Where level = 2
 Connect By Prior (Salary) > Salary)
Group By level,Department
)

Select 
    Employeeid
    ,EmployeeName
    ,Department
    ,Salary
From plc2_employees e1
Inner Join Cte e2 On e1.Department = e2.Department
Order By 
    e1.Department
    , e1.Salary desc
    ,e1.EmployeeID

как-то не работает... Я не получаю правильный результат. Может ли кто-нибудь помочь мне.


person user1025901    schedule 02.11.2011    source источник
comment
Вас интересует не Ларри Эллисон, а кто-то еще из Oracle? (Извините, мне так эта тема звучала...)   -  person Jamie F    schedule 02.11.2011
comment
Да, вопрос похож на этот и другой вопрос SO. Я уже видел.. но я пытаюсь решить его, используя подход Connect by.. Причина, по которой я новичок в этом и пытаюсь реализовать это в этом контексте...   -  person user1025901    schedule 02.11.2011
comment
Вы не можете решить эту проблему с помощью рекурсивного запроса (хорошо, вы могли бы это сделать, но это не правильный инструмент для работы). Конкретная проблема, с которой вы столкнулись, заключается в том, что пункт Connect By Prior (Salary) > Salary приводит к тому, что каждая зарплата присоединяется к каждой зарплате ниже нее.   -  person Allan    schedule 02.11.2011
comment
Аллан, я пытаюсь улучшить первый предложенный здесь метод (techforum4u.com/entry.php/).. пожалуйста, помогите   -  person user1025901    schedule 02.11.2011
comment
@ user1025901: Метод, предложенный в этой ссылке, плохо продуман. Предположим, у вас есть 1000 сотрудников: с помощью этого метода вы создадите промежуточный результирующий набор из 499 500 (при объединении неравенства будет создано n*(n-1)/2 записей, если ни одна из них не будет равна) записей, чтобы найти одну запись, которую вы ищете. Это невероятно неэффективно, особенно когда есть известное решение, в котором используется функция, лучше подходящая для задачи (аналитические запросы).   -  person Allan    schedule 02.11.2011


Ответы (9)


Если вы собираетесь научиться работать с CONNECT BY, вы должны сначала найти проблему, подходящую для этой конструкции. CONNECT BY предназначен для обработки данных в иерархической форме, которой нет в вашем примере. Зарплаты не связаны друг с другом иерархическим образом. Попытка принудительно подогнать конструкцию к неправильной проблеме разочаровывает и на самом деле ничему вас не учит.

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

person DCookie    schedule 02.11.2011

Что-то вроде

select * from
(
select EmployeeID, EmployeeName, Department, Salary, 
rank () over (partition by Department order by Salary desc) r
from PLC2_Employees
)
where r = 2

Изменить - протестировал его, и он дает ожидаемый ответ.

person Greg Reynolds    schedule 02.11.2011
comment
Ну, я знаю, что это подходы ... даже это также можно сделать с помощью Dense_Rank ... + связанный подзапрос и т. Д. Я пробую другой подход для его решения, используя соединение, поскольку я новичок в этом ... - person user1025901; 02.11.2011
comment
Хорошо, это не было ясно из вашего первоначального вопроса. Не уверен, что соединение с помощью является хорошим подходом для этого. - person Greg Reynolds; 02.11.2011
comment
Привет, Грег, я в основном пытаюсь улучшить первое решение, предложенное здесь (techforum4u.com/entry.php/) - person user1025901; 02.11.2011

START WITH … CONNECT BY предназначен для изучения данных, образующих график, путем изучения всех возможных нисходящих путей. Вы указываете корневые узлы в предложении START WITH и соединения узлов в предложении CONNECT BY (не в предложении WHERE).

Фильтры предложения WHERE будут обрабатываться после иерархических условий, одинаковых для GROUP BY и HAVING (конечно, потому что GROUP BY вычисляется после WHERE).

Поэтому вы ДОЛЖНЫ здесь CONNECT BY PRIOR department = department например. Вы также должны избегать того, чтобы соединение узла выполнялось между двумя зарплатами, когда есть промежуточная зарплата.

Поэтому окончательный запрос будет выглядеть так:

SELECT level
     , Department
     , Salary
  FROM plc2_employees pe1
 START WITH pe1.salary = (select max(salary) from plc2_employees pe2 WHERE pe2.Department = pe1.Department)
 CONNECT BY PRIOR pe1.Department = pe1.Department
        AND PRIOR pe1.Salary > pe1.Salary
        AND PRIOR pe1.Salary = ( SELECT MIN(Salary) FROM plc2_employees pe3
                                  WHERE pe3.Department = pe1.Department
                                    AND pe3.Salary > pe1.Salary
                               )

Условие рекурсии гласит, что между дочерней строкой и родительской строкой нет промежуточной зарплаты.

Учтите, что это действительно будет неэффективно…

person Benoit    schedule 02.11.2011

Попробуйте это, это дает вторую по величине зарплату

select MAX(Salary) as Salary 
from Employee_salary 
where Salary not in (select MAX(Salary) from Employee_salary) 
person Community    schedule 01.09.2013

Вы можете использовать этот запрос:

select * from 
employee e1 
where 2 = (select count (distinct (salary)) 
from employee e2 
where e2.salary >=e1.salary);
person Ajay Kumar Jaiswal    schedule 14.05.2018

узнать вторую по величине зарплату из таблицы сотрудников, имеющей столбец зарплаты: База данных: DB2

with t as
(
select distinct salary from employee order by salary desc
),
tr as 
(
select salary, row_Number() over() r from t 
)
select salary from tr where r = 2
person ajit singh    schedule 26.02.2015

Попробуйте это, это дает вторую по величине зарплату...

select MAX(Salary) as Salary 
from Employee_salary 
where Salary not in (select MAX(Salary) from Employee_salary )

Если вы хотите найти n-ю самую высокую зарплату, вы можете использовать следующий запрос .... вам нужно сделать всего одно изменение ..... Поместите значение N = n-е самое высокое

Ваше здоровье....:)

SELECT * FROM Employee_salary Emp1 
WHERE (N-1) = (SELECT COUNT(DISTINCT(Emp2.Salary)) 
               FROM Employee_salary Emp2 
               WHERE Emp2.Salary > Emp1.Salary)
person Community    schedule 01.09.2013
comment
Попробуйте это, проверено :) - person ; 20.08.2018

Это сработает -

SELECT MIN(Salary) 
FROM employee 
WHERE salary IN (SELECT TOP 2 salary FROM employee ORDER BY salary DESC)
person tusharD    schedule 02.09.2015

Сначала выберите различные зарплаты в порядке убывания (от наибольшей к наименьшей), из этого набора выберите 2 лучших и расположите их в порядке возрастания (разместив номер 2 сверху), затем из этих 2 выберите 1-й:

select top 1 s.Salary
  from 
   (select top 2 t.Salary
      from
          (select distinct Salary
             from PLC2_Employees
            order by Salary desc) t
     order by Salary asc) s
person Parmenion    schedule 02.11.2011
comment
Oracle не поддерживает TOP. - person Allan; 02.11.2011
comment
Да, это правда (верхняя часть не поддерживается в Orcle, мы можем использовать для этого Row_Number() или RowNum).. и также этот запрос не будет обрабатывать связи (если выполняется на сервере sql или других rdbms, поддерживающих TOP) надеюсь - person user1025901; 02.11.2011