【问题标题】:Select the nth highest value in a column and null if it doesn't exist选择列中的第 n 个最大值,如果不存在则为 null
【发布时间】:2017-11-07 00:30:29
【问题描述】:

我正在尝试解决 LeetCode 问题https://leetcode.com/problems/second-highest-salary/description/;到目前为止我的解决方案(另见http://sqlfiddle.com/#!9/4752cb/1)是:

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

问题是我的解决方案在以下测试用例上失败了:

换句话说,它只是不返回结果而不是返回NULL。如果没有第二高的薪水,如何让它返回NULL

更新

Return a value if no record is found之后,我尝试将查询封装在一个子查询中:

SELECT (SELECT Salary 
FROM Employee 
ORDER BY Salary DESC LIMIT 1, 1) AS SecondHighestSalary;

但是,这在另一个测试用例中失败,其中有两个员工的薪水相同:

在这种情况下,我们显然也应该返回NULL。如何调整上面的“更接近解决方案”查询来处理这个问题?

【问题讨论】:

  • 如果两个(或更多)员工的最高薪水相同怎么办……我们返回最高薪水吗?还是我们退回下一个较低的工资?
  • Spencer,在这种情况下,我们返回下一个较低的薪水(尽管这在 LeetCode 的问题陈述中并不清楚;我是从一个失败的测试用例中发现的)。
  • 这里的问题是.. 如果我们可以说 20 个人的薪水第二高,那么该特定薪水的相关人员怎么样.. 如果我们可以确定谁是该特定薪水的人只需要一个带有不同查询的薪水。我认为LeetCode's problem 不太清楚。

标签: mysql


【解决方案1】:

这是一个最终通过测试的查询:

SELECT (SELECT DISTINCT Salary 
FROM Employee 
ORDER BY Salary DESC LIMIT 1, 1) AS SecondHighestSalary;

它似乎比其他解决方案更直观,不是吗?

【讨论】:

    【解决方案2】:

    选择另一行返回空值,使用union all 保留顺序,然后只返回第一行:

    SELECT * FROM
    (
        SELECT Salary AS SecondHighestSalary 
        FROM Employee 
        ORDER BY Salary DESC LIMIT 1, 1
        UNION ALL
        SELECT NULL
    )
    LIMIT 1
    

    【讨论】:

      【解决方案3】:

      这里的 OFFSET 1 表示没有第一个(例如:如果您不想显示第一个 2,那么 OFFSET 将为 2)

      SELECT
          Salary AS SecondHighestSalary 
      FROM
          Employee
      
      ORDER BY
          Salary
      
      LIMIT 1 OFFSET 1;
      

      【讨论】:

        【解决方案4】:

        对于当前查询,我们可以将其包装在另一个查询中,并使用聚合函数

           SELECT MAX(v.salary) AS SecondHighestSalary
             FROM (
                    SELECT e.Salary
                      FROM Employee e
                     ORDER BY e.Salary DESC
                     LIMIT 1, 1
                  ) v
        

        这一套应该给第二高的薪水多少...

         id  salary
         --  ------
          1    1000
          2    1000
          4     750
        

        我们应该返回 1000 还是返回 750?如果我们想返回 750,我们可以这样做:

           SELECT MAX(s.salary) AS SecondHighestSalary
             FROM ( SELECT MAX(e.salary) AS max_salary
                      FROM Employee e
                  ) h
             JOIN Employee s
               ON s.salary < h.max_salary
        

        【讨论】:

          【解决方案5】:

          使用IFNULL

          SELECT
            IFNULL( (
            SELECT DISTINCT
              `salary` 
            FROM
              `Employee` 
            ORDER BY
              `salary` DESC LIMIT 1, 1), NULL )
          )
          AS `SecondHighestSalary`
          
          

          如果第一个查询没有返回任何内容,则返回 NULL

          【讨论】:

            【解决方案6】:

            Safe with Distinct 不包括空值:

            SELECT distinct Salary AS SecondHighestSalary 
            FROM Employee where salary is not null ORDER BY salary desc limit 1,1
            

            【讨论】:

              【解决方案7】:

              你可以先得到前两个值 然后分别处理null的情况和正常的情况

              select case
              when min(top2.salary)=max(top2.salary) then null
              else min(top2.salary) end
              as SecondHighestSalary
              from 
              (select e.salary from employee e order by e.salary desc limit 2) as top2; 
              

              【讨论】:

                猜你喜欢
                • 2017-09-20
                • 2013-05-26
                • 2013-06-01
                • 2019-11-23
                • 1970-01-01
                • 2014-02-21
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多