Reputation: 15
I need to display 2nd highest salary for each dept, if employee having same salary then display salary with least empno
.
I have emp
table as below in which deptno
20 have 2nd highest salary 3000 for two empno
7788 and 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
I have written below code:
select * from (
select e.*, row_number() over (partition by deptno order by sal desc ) rn
from emp e
)where rn = 2;
I got below result. But as per my requirement, if any employee having same salary for that department, then salary with least employee id should be display but in my case empno 7902 is displayed. But I need to display salary with empno 7788:
EMPNO ENAME JOB SAL DEPTNO
7782 CLARK MANAGER 2450 10
7902 FORD ANALYST 3000 20
7499 ALLEN SALESMAN 1600 30
How to achieve this?
Upvotes: 1
Views: 387
Reputation: 1250
you can use RANK()
. The difference between RANK()
and ROW_NUMBER()
is that RANK()
will give same rank for same numbers, so you will see two 2
for department 20. Then you wrap it up with another ROW_NUMBER() to grab the least 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
And here is the result:
EMPNO DEPTNO salary_rank
7782 10 2
7788 20 2
7499 30 2
Upvotes: 0
Reputation: 51892
This query gives the correct result on 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;
Result
EMPNO ENAME JOB SAL DEPTNO rn
7782 CLARK MANAGER 2450 10 2
7788 SCOTT ANALYST 3000 20 2
7499 ALLEN SALESMAN 1600 30 2
Upvotes: 1
Reputation: 547
Try this..
You have to add empno in order by clause with asc
select * from ( select e.*, row_number() over (partition by deptno order by
sal desc,empno asc ) rn
from emp e) where rn = 2;
Upvotes: 1