Cas SQL sans étiquetage null

Oct 04 2020

J'essaye de faire ce problème de code Leet :

Écrivez une requête SQL pour obtenir le deuxième salaire le plus élevé de la table Employee.

+----+--------+
| Id | Salary |
+----+--------+
| 1  | 100    |
| 2  | 200    |
| 3  | 300    |
+----+--------+

Par exemple, étant donné la table Employee ci-dessus, la requête doit renvoyer 200 comme deuxième salaire le plus élevé. S'il n'y a pas de deuxième salaire le plus élevé, la requête doit renvoyer null.

+---------------------+
| SecondHighestSalary |
+---------------------+
| 200                 |
+---------------------+

J'essaye de donner cette solution:

SELECT 
      CASE WHEN Salary = '' 
         THEN NULL 
         ELSE Salary END SecondHighestSalary 
   FROM 
      Employee 
   ORDER BY 
      SecondHighestSalary 
   LIMIT 1,1;

Quand il y a un deuxième salaire, cela fonctionne bien et renvoie la sortie. Cependant, lorsqu'il n'y a pas de deuxième salaire et qu'un seul salaire, seule une chaîne vide est renvoyée. J'essaie de revenir NULL, cependant, cela ne revient pas NULLcomme ce que j'ai écrit dans ma requête. Comment puis-je réparer cela?

Réponses

3 Barmar Oct 04 2020 at 07:11

Votre CASEexpression teste le salaire dans chaque ligne du tableau, et non celui sélectionné par la LIMITclause. Le classement est effectué après la génération des valeurs dans la SELECTliste, car vous pouvez classer par ces valeurs calculées.

Étant donné qu'aucun des salaires n'est une chaîne vide, la condition dans votre CASEne sera jamais vraie, donc elle renvoie toujours la Salaryvaleur. Par conséquent, votre requête équivaut à

SELECT Salary AS SecondHighestSalary
FROM Employee
ORDER BY SecondHighestSalary
LIMIT 1, 1

Autres choses:

  1. Vous devez utiliser DESCpour obtenir le salaire le plus élevé au début. Donc, même si votre méthode fonctionnait, elle trouverait le deuxième salaire le plus bas .
  2. Votre méthode ne gère pas le cas où plusieurs employés sont à égalité pour le salaire le plus élevé. LIMIT 1, 1renverra la deuxième ligne, qui sera l'un des employés à égalité.

Vous pouvez résoudre le deuxième problème à l'aide d'une sous-requête qui supprime les doublons:

SELECT DISTINCT Salary
FROM Employee

Une dernière requête pourrait donc être:

SELECT IF(COUNT(*) > 0, MAX(Salary), NULL) AS SecondHighestSalary
FROM (
    SELECT DISTINCT Salary
    FROM Employee
    ORDER BY Salary DESC
    LIMIT 1, 1
) AS x
Strawberry Oct 04 2020 at 06:11

Par exemple

 select max(salary) salary 
   from employee 
 where salary not in 
 (select max(salary) from employee)
Runa Oct 04 2020 at 06:45

Vous pouvez utiliser cette solution, où s'il n'y a pas de deuxième salaire le plus élevé retournera NULL. Sinon retournera le deuxième salaire le plus élevé

SELECT 
   IFNULL(MIN(Salary) , 'NULL') as SecondHighestSalary
FROM
    Employee
WHERE salary > (SELECT MIN(salary)
                 FROM Employee)

Ou si vous voulez que DB par défaut null, supprimez simplement la condition IFNULL

SELECT 
   MIN(Salary) as SecondHighestSalary
FROM
    Employee
WHERE salary > (SELECT MIN(salary)
                 FROM Employee)