J'ai trouvé une requête pour trouver le nième salaire le plus élevé de la table des employés, mais je ne comprends pas la logique de (N-1)?
EmpID Salary
1 90000
2 80000
3 54000
4 37000
5 12000
6 69000
7 50000
SELECT * FROM Employee E1
WHERE (N-1) = (
SELECT COUNT(DISTINCT(E2.Salary))
FROM Employee E2
WHERE E2.Salary > E1.Salary
)
Si n = 4, alors comment fonctionne la requête? Je suis un débutant complet en SQL, aide s'il vous plaît!
Une autre façon d'écrire cette requête utiliserait le 2012+ OFFSET / FETCH
Syntaxe pour trouver le nième salaire:
; WITH Nth AS -- To find the Nth highest salary,
(
SELECT DISTINCT Salary -- get all the distinct salary values
FROM Employee
ORDER BY Salary DESC -- order them from high to low
OFFSET 3 ROWS -- skip (N-1) values
FETCH NEXT 1 ROWS ONLY -- and keep the next one (Nth).
)
SELECT EmpID, Salary -- Then show
FROM Employee -- all employees that have
WHERE Salary = (SELECT Salary FROM Nth) ; -- have a salary equal to that.
ou pour les versions avant 2012, en 2 étapes. Premier commandant par DESC
, alors par ASC
:
; WITH TopN AS -- Find the top N salaries,
(
SELECT DISTINCT TOP (4) Salary
FROM Employee
ORDER BY Salary DESC
),
Nth AS -- then keep only the Nth one,
(
SELECT TOP (1) Salary
FROM TopN
ORDER BY Salary
)
SELECT EmpID, Salary -- and show
FROM Employee -- all employees that have
WHERE Salary = (SELECT Salary FROM Nth) ; -- have a salary equal to that.
Test dans sqlfiddle
Si n = 4, il renvoie le salaire où il y a 4-1 = 3 salaires plus élevés, en d'autres termes, il renvoie le 4ème le plus élevé.
Exemple:
Salaries (500, 400, 400, 300, 250, 200).
Le résultat souhaité est (250) (le quatrième que nous comptons '400' une seule fois en raison de la DISTINCT
). N-1 = 3 signifie qu'il existe 3 salaires distincts supérieurs à 250, qui sont (500, 400, 300).
Dans votre exemple, où il n'y a pas de salaire répété, le résultat souhaité est (5400), qui est le 4ème le plus élevé. Donc, la requête renvoie le salaire où le nombre de salaires plus élevé est de 4-1.
Declare @nth varchar(4) = '10' ;
Declare @inner varchar(max) =
'Select top ' + @nth + ' * from employee order by salary desc'
Declare @outer varchar(max) =
'Select top 1 * from (' + @inner +') a order by salary';
--exec (@inner)
exec (@outer);
C'est comme ça que j'ai abordé cela avec TSQL. Je pensais à mi-pensée quant à la paramétrisation de la commande par ainsi que de manière à pouvoir basculer et à faire le nième ou le plus bas.