Случай SQL, когда не указывается значение null

Oct 04 2020

Я пытаюсь решить эту проблему с кодом Leet :

Напишите SQL-запрос, чтобы получить вторую по величине зарплату из таблицы «Сотрудник».

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

Например, учитывая приведенную выше таблицу сотрудников, запрос должен вернуть 200 в качестве второй по величине зарплаты. Если второй по величине заработной платы нет, запрос должен вернуть значение null.

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

Я пытаюсь дать такое решение:

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

Когда есть вторую зарплату, нормально работает и отдачу возвращает. Однако, когда нет второй зарплаты и есть только одна зарплата, возвращается только пустая строка. Я пытаюсь вернуться NULL, однако он не возвращается, NULLкак то, что я написал в своем запросе. Как я могу это исправить?

Ответы

3 Barmar Oct 04 2020 at 07:11

Ваше CASEвыражение проверяет зарплату в каждой строке таблицы, а не в той, которая выбрана в LIMITпредложении. Упорядочивание выполняется после создания значений в SELECTсписке, поскольку вы можете упорядочить их по рассчитанным значениям.

Поскольку ни одна из зарплат не является пустой строкой, условие в your CASEникогда не будет истинным, поэтому оно всегда возвращает Salaryзначение. В результате ваш запрос эквивалентен

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

Другие вещи:

  1. Вам нужно использовать, DESCчтобы получить самую высокую зарплату в начале. Так что, даже если бы ваш метод работал, он бы нашел вторую самую низкую зарплату.
  2. Ваш метод не подходит для случая, когда несколько сотрудников имеют самую высокую зарплату. LIMIT 1, 1вернет вторую строку, в которой будет один из связанных сотрудников.

Вторую проблему можно решить с помощью подзапроса, удаляющего дубликаты:

SELECT DISTINCT Salary
FROM Employee

Итак, последний запрос может быть таким:

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

Например

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

Вы можете использовать это решение, где, если нет второй по величине зарплаты, вернет NULL. В противном случае вернет вторую по величине зарплату

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

Или, если вы хотите, чтобы DB по умолчанию был равен нулю, просто удалите условие IFNULL

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