Caso SQL Quando non si etichetta null

Oct 04 2020

Sto cercando di fare questo problema Leet Code :

Scrivi una query SQL per ottenere il secondo stipendio più alto dalla tabella Employee.

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

Ad esempio, data la tabella Employee precedente, la query dovrebbe restituire 200 come secondo stipendio più alto. Se non è presente il secondo stipendio più alto, la query dovrebbe restituire null.

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

Sto cercando di dare questa soluzione:

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

Quando c'è un secondo stipendio, funziona bene e restituisce l'output. Tuttavia, quando non c'è un secondo stipendio e c'è solo uno stipendio, viene restituita solo una stringa vuota. Sto cercando di tornare NULL, tuttavia, non restituisce NULLciò che ho scritto nella mia domanda. Come posso risolvere questo problema?

Risposte

3 Barmar Oct 04 2020 at 07:11

La tua CASEespressione sta testando lo stipendio in ogni riga della tabella, non quello selezionato dalla LIMITclausola. L'ordine viene eseguito dopo aver generato i valori SELECTnell'elenco, poiché è possibile ordinare in base a quei valori calcolati.

Poiché nessuno degli stipendi è una stringa vuota, la condizione nel tuo CASEnon sarà mai vera, quindi restituisce sempre il Salaryvalore. Di conseguenza, la tua query è equivalente a

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

Altre cose:

  1. È necessario utilizzare DESCper ottenere lo stipendio più alto all'inizio. Quindi, anche se il tuo metodo funzionasse, troverebbe il secondo stipendio più basso .
  2. Il tuo metodo non gestisce il caso in cui più dipendenti sono legati per lo stipendio più alto. LIMIT 1, 1restituirà la seconda fila, che sarà quella dei dipendenti legati.

Puoi risolvere il secondo problema utilizzando una sottoquery che rimuove i duplicati:

SELECT DISTINCT Salary
FROM Employee

Quindi una domanda finale potrebbe essere:

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

Per esempio

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

È possibile utilizzare questa soluzione, dove se non c'è un secondo stipendio più alto verrà restituito NULL. Altrimenti restituirà il secondo stipendio più alto

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

Oppure, se si desidera che il valore predefinito del DB sia null, è sufficiente rimuovere la condizione IFNULL

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