检查Postgres复合字段是否为空/空

时间:2014-03-31 13:42:20

标签: sql postgresql null composite

使用postgres composite types,您基本上可以构建一个字段,其结构被定义为另一个表。我有一个名为“person”类型的“收件人”的复合字段。在我的特定方案中,此收件人字段通常为空。检查复合字段是否为空的正确方法是什么。我试过了:

select * from bla where recipient is not null
select * from bla where recipient is null
select * from bla where recipient = null
select * from bla where recipient != null

在所有这些情况下,它都不会返回任何内容。那么如何正确检查复合值是否为空?

更新

经过多次阅读后,看起来这是我的问题:

  

有人可能会认为!(x IS NULL) = x IS NOT NULL在所有情况下都是正确的。但是有一个例外 - 复合类型。当复合值的一个字段为NULL而另一个字段为NOT NULL时,则两个运算符的结果均为false。仅当所有字段均为IS NULL时,NULL才为真。仅当所有字段均为IS NOT NULL时,NOT NULL才为真。对于介于两者之间的任何情况,两个运算符都返回false。

我确实有一些空字段,有些字段不是。我希望如果复合字段中的任何项不为null,则该字段将被视为非NULL,而不是当所有项都不为空时。除了检查每个字段之外,还有其他方法吗?

2 个答案:

答案 0 :(得分:16)

IS NULLIS NOT NULL也适用于复杂类型,所以这两个应该是合适的:

select * from bla where recipient is not null
select * from bla where recipient is null

答案 1 :(得分:13)

要捕获并非复合值(行/记录)的所有字段为NULL的情况:

SELECT *
FROM   bla
WHERE  NOT (recipient IS NULL);
如果所有字段均为<row-type> is NULL,则

TRUE仅返回NULL
如果所有字段均为<row-type> is NOT NULL,则TRUE仅返回NOT NULL

括号是可选的。无论如何,运算符优先级对我们有利。

测试NULL

的行/记录

展示各种选择:

CREATE TEMP TABLE recipient (r text, i int);  -- to register the row type

SELECT recipient
     , recipient IS NULL         AS all_null
     , recipient IS NOT NULL     AS all_notnull
     , NOT recipient IS NULL     AS some_notnull
     , NOT recipient IS NOT NULL AS some_null
FROM (
   VALUES
    (('foo', 1   )::recipient)
  , ((NULL , 2   )::recipient)
  , ((NULL , NULL)::recipient)
   ) AS tbl(recipient);

结果:

 recipient | all_null | all_notnull | some_notnull | some_null
-----------+----------+-------------+--------------+-----------
 (foo,1)   | f        | t           | t            | f
 (,2)      | f        | f           | t            | t
 (,)       | t        | f           | f            | t

SQL Fiddle.

相关: