【问题标题】:Return NULL when no records found Postgres没有找到记录时返回 NULL Postgres
【发布时间】:2022-01-06 01:27:54
【问题描述】:

我正在努力解决 Leetcode 的第二高薪水(https://leetcode.com/problems/second-highest-salary/)。这是我在 postgres 上实现的:

select foo.salary as "SecondHighestSalary"
from 
(select salary,
dense_rank() over (order by salary desc) as rank
from Employee) foo
where rank = 2;

但问题是,如果没有 rank = 2 的记录,我需要返回 NULL。 然后我尝试了

select (case
    when count(1) = 0 then NULL
    else salary
    end
)
from 
(select salary,
dense_rank() over (order by salary desc) as rank
from Employee) foo
where rank = 2
group by salary;

但它仍然没有返回任何记录。 没有返回记录时如何输出NULL?

【问题讨论】:

  • 链接的exercise from leetcode 没有给出正确的表定义。 salary 是否可以为 NULL 很重要。鉴于他们要求 NULL 结果,这是一个相当大的遗漏。

标签: sql postgresql


【解决方案1】:

该解决方案不起作用,因为没有可供 case 操作的行。

您可以使用coalesce 和子选择。

将其重写为 CTE 使子选择更加紧凑。

with ranked_salaries as (
  select
    salary,
    dense_rank() over (order by salary desc) as "rank"
  from Employee
)
select
  coalesce(
    (select salary from ranked_salaries where "rank" = 2),
    null
  );

注意this is a simpler and faster approach for this particular problem。

select max(salary)
from Employee
where salary < (select max(salary) from Employee)

如果薪水被索引,这应该很快。

【讨论】:

    【解决方案2】:
    select max(salary) as "SecondHighestSalary"
    from 
        (select salary,
            dense_rank() over (order by salary desc) as rnk
        from Employee) foo
    where rnk = 2;
    

    对输出使用虚拟聚合将保证返回一行。它还处理捆绑行的可能性。

    【讨论】:

      【解决方案3】:

      你实际上不需要COALESCE,只需要一个外部SELECT:

      SELECT (
         SELECT salary FROM (
            SELECT salary, dense_rank() OVER (ORDER BY salary DESC NULLS LAST) AS rank
            FROM   employee
            ) sub
         WHERE  rank = 2
         LIMIT  1
         ) AS second_highest_salary;
      

      见:

      如果salary 可以是NULL,请务必添加NULLS LAST,否则您会大吃一惊。 (您将获得最高的薪水。)请参阅:

      而rank = 2可以有多行,所以加上LIMIT 1。

      使用salary 上的索引,Schwern's 2nd query 将大大加快,虽然 - 同时避开 NULL 问题,因为 max() 排除 NULL 值,并避开“无行”问题,因为聚合函数总是返回一行,在没有值的情况下默认为NULL。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-24
        • 1970-01-01
        • 2012-05-20
        • 1970-01-01
        • 1970-01-01
        • 2011-12-27
        • 1970-01-01
        • 2014-07-16
        相关资源
        最近更新 更多