COALESCE 和 CASE 之间的区别 IS NOT NULL

Difference between COALESCE and CASE IS NOT NULL

我正在将一些报告从 jasper 报告 SQL 替换为 JAVA EE 本机查询
我找到了一个 SQL 查询 (postgres),其中包含:

    SELECT
        --many rows
        (CASE WHEN description IS NOT NULL THEN description ELSE '' END), --varchar(200)
        COALESCE(house_number, ''), --varchar(20)
        COALESCE(floor_number, ''), --varchar(20)
        (CASE WHEN (power IS NOT NULL AND power > 0) THEN power ELSE 0 END)
   FROM
       --table

使用 COALESCE 和 CASE IS NOT NULL 有什么区别吗?

COALESCE(description, '')

在某些情况下 return 会有不同的结果吗?

COALESCE(CAST(power AS TEXT), '0')

或者一个在某些情况下比另一个更快?

在大多数情况下,两者是相同的。我认为标准将 COALESCE(X, Y) 定义为:

(CASE WHEN X IS NOT NULL THEN X ELSE Y END)

在大多数情况下,这完全符合您的预期。

有一处不同。对该标准的一种解释是,当值不是 NULL 时,X 被计算两次。这在大多数情况下没有区别(在大多数情况下,无论如何都会缓存该值)。

虽然 Postgres 没有这样做。 它实现了对标准更合理的解释。换句话说,这两者在 Postgres 中并不完全相同,因为 Postgres 足够聪明,可以对第一个表达式进行一次计算,无论它是 NULL 还是不是

如果你有一个 volatile 函数(它的值会改变),你可以看到效果。在 Postgres 中,下面的 returns "x" 和 "y" 的次数差不多:

select v.x, coalesce(case when random() > 0.5 then 'x' end, 'y')
from (values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10)) v(x);

SQL 服务器中的等效代码 returns "y" 一半时间和 "x" 和 NULL 四分之一时间——因为 SQL 服务器将这两个构造视为完全等价,并在某些情况下对第一个参数求值两次。

您可以在 db<>fiddles here and here.

中看到它

然而,SQL