1
votes

SQL - Affiche le deuxième salaire le plus élevé pour chaque service, si l'employé a le même salaire, affiche le salaire avec le moins d'empno

Je dois afficher le deuxième salaire le plus élevé pour chaque service, si un employé a le même salaire, alors afficher le salaire avec le moins empno .

J'ai le tableau emp comme ci-dessous dans dont deptno 20 ont le deuxième salaire le plus élevé 3000 pour deux empno 7788 et 7902.

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

J'ai écrit le code ci-dessous:

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

J'ai obtenu le résultat ci-dessous. Mais selon mes exigences, si un employé ayant le même salaire pour ce département, le salaire avec le moins d'identifiant d'employé doit être affiché, mais dans mon cas, l'empno 7902 s'affiche. Mais j'ai besoin d'afficher le salaire avec empno 7788:

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

Comment y parvenir?


4 commentaires

Ne pouvez-vous pas simplement ajouter empno à votre ORDER BY après le sal?


Je l'ai essayé ... ne fonctionne pas


quels rdbms utilisez-vous, veuillez marquer votre question avec.


Le mien est oracle.


3 Réponses :


1
votes

Essayez ceci ..

Vous devez ajouter empno dans l'ordre par clause avec 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 commentaires

0
votes

vous pouvez utiliser RANK () . La différence entre RANK () et ROW_NUMBER () est que RANK () donnera le même rang pour les mêmes nombres, donc vous verrez deux 2 pour le département 20. Ensuite, vous terminez avec un autre ROW_NUMBER () pour saisir le moins EMPNO:

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

Et voici le résultat:

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


1 commentaires

Ici, le département 20 a le même salaire et j'ai besoin d'un salaire avec le moins d'empno seulement, soit 7788



1
votes

Cette requête donne le résultat correct sur MySql

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

Résultat

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

dbfiddle avec Oracle


4 commentaires

le mien est oracle.


lorsque j'utilise la requête ci-dessous, j'ai obtenu le résultat. select * from (select e. *, row_number () over (partition by deptno order by sal desc, empno desc) rn from emp e) s where rn = 2; Mais pourquoi empno desc fonctionne pas asc


@iteng Lorsque j'exécute ma requête sur oracle en utilisant dbfiddle, cela fonctionne comme prévu, voir le lien dans la réponse


Celui-ci est plus élégant ~~