null的计算结果为false

Clo*_*eto 11 postgresql

今天我对这种case行为感到惊讶:

select case when null then true else false end;
 case 
------
 f
Run Code Online (Sandbox Code Playgroud)

我希望它返回,null因为一个null铸造到布尔的yelds a null而不是false:

select null::boolean is null;
 ?column? 
----------
 t
Run Code Online (Sandbox Code Playgroud)

有关这种行为的理由的任何评论?我错过了什么?

小智 20

使用类似的东西

case when p.parent_id is null then false else true end as has_parent
Run Code Online (Sandbox Code Playgroud)


Tho*_*ues 18

如果您(也)需要类似的东西

if column is null then 'value' 
Run Code Online (Sandbox Code Playgroud)

使用:

COALESCE(column_name, 'replacment for null value') as column_name
Run Code Online (Sandbox Code Playgroud)

如果您仍需要案例陈述,请使用:

case COALESCE(column_name, 'asdf') 
when 'asdf' then true
else false
end as desired_column_name
Run Code Online (Sandbox Code Playgroud)


Cra*_*ger 13

您正在考虑CASE表达式,就像它将null函数或运算符作为输入一样,其中null输入通常会导致null输出:

regress=> SELECT 't'::boolean = NULL::boolean;
 bool 
------

(1 row)
Run Code Online (Sandbox Code Playgroud)

事实上WHERE,就行处理而言,它的行为就像一个子句:

craig=> SELECT 't' WHERE NULL;
 ?column? 
----------
(0 rows)
Run Code Online (Sandbox Code Playgroud)

WHERE子句中 - 并且在中CASE,NULL测试表达式的结果被视为"不为真,因此为假".在某些方面,令人遗憾的是SQL标准没有NULLWHERE表达式中产生错误而不是将其视为错误,但事实就是这样.

这是NULL人格分裂的另一个痛苦症状,其中SQL规范无法确定是否NULL意味着"未知/未定义的值"或"缺少值",就像NULLs和聚合的可怕混乱一样.

  • @ClodoaldoNeto 是的,这几乎是规范和理智世界冲突的政策。不过,在这种情况下,我认为这是相当合理的;`CASE` 不是一个函数,它是一个有自己规则的特殊表达式。无论如何,函数可以有特殊的 null 处理;见证Oracle的“解码”。如果不重写 SQL 规范以完全解决有关空值的混乱,PostgreSQL 就无法解决此问题,在此过程中使其与其他所有内容完全不兼容。 (2认同)

Gri*_*y K 5

您可以使用“选择”来检查“数据”列是否为空:

select 
  ID,
  case (select 1 where DATA is null)
    when 1 then 'no data'
    else data
  end
from ...
Run Code Online (Sandbox Code Playgroud)