【问题标题】:Check if a Postgres composite field is null/empty检查 Postgres 复合字段是否为空/空
【发布时间】:2014-03-31 13:42:19
【问题描述】:

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

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,那么这两个运算符的结果都是假的。 IS NULL 为真,仅当所有字段均为NULL 时。 IS NOT NULL 为真,仅当所有字段均为 NOT NULL 时。对于介于两者之间的任何情况,两个运算符都返回 false。

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

【问题讨论】:

    标签: sql postgresql null composite


    【解决方案1】:

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

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

    【讨论】:

    • 请注意,复杂/行/记录类型的IS NULL / IS NOT NULL 是特殊的。
    【解决方案2】:

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

    SELECT *
    FROM   bla
    WHERE  NOT (recipient IS NULL);

    <row-type> is NULL 仅在 所有 字段为 NULL 时返回 TRUE
    <row-type> is NOT NULL 仅在 所有 字段为 @987654332 时返回 TRUE @。

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

    演示

    CREATE TYPE recipient AS (r text, i int);
    
    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)
      , (NULL)
       ) 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
     null      | t        | f           | f            | t
    

    db小提琴here
    sqlfiddle

    相关:

    【讨论】:

    • is [not] null 只能评估为 true/false 所以看起来(对我来说)is not true 不是必需的,只需 not (recipient is [not] null) 就足够了。我错过了什么?
    • @ClodoaldoNeto:你是对的,这样做更简单。我用你的输入更新了答案。
    猜你喜欢
    • 1970-01-01
    • 2012-02-21
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多