SQL - отображать 2-ую самую высокую зарплату для каждого отдела, если сотрудник имеет одинаковую зарплату, то отображать зарплату с наименьшим empno - PullRequest
1 голос
/ 20 апреля 2019

Мне нужно отображать 2-ую самую высокую зарплату для каждого отдела, если работник имеет одинаковую зарплату, то отображает зарплату с наименьшим значением empno.

У меня есть таблица emp, как показано ниже, в которой deptno 20 имеют 2-ую наивысшую зарплату 3000 на двоих empno 7788 и 7902.

EMPNO   ENAME   JOB  SAL    DEPTNO
7698    BLAKE   MANAGER  2850   30
7844    TURNER  SALESMAN 1500   30
7499    ALLEN   SALESMAN 1600   30
7654    MARTIN  SALESMAN 1250   30
7521    WARD    SALESMAN 1250   30
7900    JAMES   CLERK    950    30
7788    SCOTT   ANALYST  3000   20
7566    JONES   MANAGER  2975   20
7369    SMITH   CLERK    25000  20
7876    ADAMS   CLERK    1100   20
7902    FORD    ANALYST  3000   20
7839    KING    PRESIDENT 5000  10
7934    MILLER  CLERK    1300   10
7782    CLARK   MANAGER  2450   10

Я написал ниже код:

select * from (
  select e.*, row_number() over (partition by deptno order by sal desc ) rn 
  from emp e  
)where rn = 2;

Я получил ниже результат. Но согласно моему требованию, если какой-либо сотрудник имеет одинаковую зарплату для этого отдела, то должна отображаться зарплата с наименьшим идентификатором сотрудника, но в моем случае отображается empno 7902. Но мне нужно отобразить зарплату с empno 7788:

EMPNO   ENAME   JOB       SAL   DEPTNO
7782    CLARK   MANAGER   2450  10
7902    FORD    ANALYST   3000  20
7499    ALLEN   SALESMAN  1600  30

Как этого добиться?

Ответы [ 3 ]

1 голос
/ 21 апреля 2019

Этот запрос дает правильный результат на MySql

select * from (
    select e.*, row_number() over (partition by deptno order by sal desc, empno asc ) rn 
    from emp e  
) s where rn = 2;

Результат

EMPNO   ENAME   JOB         SAL     DEPTNO  rn  
7782    CLARK   MANAGER     2450    10      2  
7788    SCOTT   ANALYST     3000    20      2   
7499    ALLEN   SALESMAN    1600    30      2

dbfiddle с использованием Oracle

1 голос
/ 20 апреля 2019

Попробуйте это ..

Вы должны добавить empno в порядке с помощью asc

    select * from ( select e.*, row_number() over (partition by deptno order by 
    sal desc,empno asc ) rn 
    from emp e) where rn = 2;
0 голосов
/ 21 апреля 2019

вы можете использовать RANK(). Разница между RANK() и ROW_NUMBER() заключается в том, что RANK() даст одинаковый ранг для тех же номеров, поэтому вы увидите два 2 для 20-го отдела. Затем вы заверните его с помощью другой ROW_NUMBER (), чтобы получить наименьшее число EMPNO :

SELECT * FROM (
SELECT
  subq.EMPNO,
  subq.DEPTNO,
  ROW_NUMBER() OVER(PARTITION BY subq.DEPTNO ORDER BY EMPNO ASC) AS empno_rownum
FROM (  
  SELECT 
    salary.EMPNO,
    salary.DEPTNO,
    RANK() OVER(PARTITION BY salary.DEPTNO ORDER BY salary.SAL DESC) AS salary_rank
  FROM salary
) AS subq
WHERE subq.salary_rank = 2
) AS subq2
WHERE subq2.empno_rownum = 1

А вот и результат:

EMPNO   DEPTNO  salary_rank
7782    10  2
7788    20  2
7499    30  2
...