SQL Case Gdy nie oznaczasz wartości null
Próbuję rozwiązać ten problem z kodem Leet :
Napisz zapytanie SQL, aby uzyskać drugą najwyższą pensję z tabeli Employee.
+----+--------+
| Id | Salary |
+----+--------+
| 1 | 100 |
| 2 | 200 |
| 3 | 300 |
+----+--------+
Na przykład, biorąc pod uwagę powyższą tabelę Pracownik, zapytanie powinno zwrócić 200 jako drugie najwyższe wynagrodzenie. Jeśli nie ma drugiego najwyższego wynagrodzenia, zapytanie powinno zwrócić wartość null.
+---------------------+
| SecondHighestSalary |
+---------------------+
| 200 |
+---------------------+
Próbuję podać takie rozwiązanie:
SELECT
CASE WHEN Salary = ''
THEN NULL
ELSE Salary END SecondHighestSalary
FROM
Employee
ORDER BY
SecondHighestSalary
LIMIT 1,1;
Kiedy jest druga pensja, działa dobrze i zwraca wynik. Jeśli jednak nie ma drugiej pensji i jest tylko jedna pensja, zwracany jest tylko pusty ciąg. Próbuję zwrócić NULL, jednak nie zwraca NULLtego, co napisałem w zapytaniu. Jak mogę to naprawić?
Odpowiedzi
Twoje CASEwyrażenie testuje wynagrodzenie w każdym wierszu tabeli, a nie w tym wybranym przez LIMITklauzulę. Kolejność jest wykonywana po wygenerowaniu wartości na SELECTliście, ponieważ można sortować według obliczonych wartości.
Ponieważ żadna z pensji nie jest pustymi ciągami, warunek w twoim CASEnigdy nie będzie prawdziwy, więc zawsze zwraca Salarywartość. W rezultacie twoje zapytanie jest równoważne z
SELECT Salary AS SecondHighestSalary
FROM Employee
ORDER BY SecondHighestSalary
LIMIT 1, 1
Inne rzeczy:
- Musisz użyć,
DESCaby uzyskać najwyższą pensję na początku. Więc nawet jeśli twoja metoda zadziała, przyniesie ona drugie najniższe wynagrodzenie. - Twoja metoda nie radzi sobie z przypadkiem, w którym wielu pracowników ma najwyższe wynagrodzenie.
LIMIT 1, 1zwróci drugi wiersz, którym będzie jeden z powiązanych pracowników.
Możesz rozwiązać drugi problem, używając podzapytania, które usuwa duplikaty:
SELECT DISTINCT Salary
FROM Employee
Więc ostatnie zapytanie może brzmieć:
SELECT IF(COUNT(*) > 0, MAX(Salary), NULL) AS SecondHighestSalary
FROM (
SELECT DISTINCT Salary
FROM Employee
ORDER BY Salary DESC
LIMIT 1, 1
) AS x
Na przykład
select max(salary) salary
from employee
where salary not in
(select max(salary) from employee)
Możesz skorzystać z tego rozwiązania, w którym jeśli nie ma drugiej najwyższej pensji, zwróci NULL. W przeciwnym razie zwróci drugie najwyższe wynagrodzenie
SELECT
IFNULL(MIN(Salary) , 'NULL') as SecondHighestSalary
FROM
Employee
WHERE salary > (SELECT MIN(salary)
FROM Employee)
Lub jeśli chcesz, aby wartość domyślna DB miała wartość null, po prostu usuń warunek IFNULL
SELECT
MIN(Salary) as SecondHighestSalary
FROM
Employee
WHERE salary > (SELECT MIN(salary)
FROM Employee)