cod*_*ama 23 sql postgresql null composite
使用postgres复合类型,您基本上可以构建一个字段,其结构被定义为另一个表.我有一个名为"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
Run Code Online (Sandbox Code Playgroud)
在所有这些情况下,它都不会返回任何内容.那么如何正确检查复合值是否为空?
UPDATE
经过一些阅读后,看起来这是我的问题:
人们可能认为
!(x IS NULL) = x IS NOT NULL在所有情况下都是如此.但是有一个例外 - 复合类型.当复合值的NULL一个字段是另一个字段时NOT NULL,则两个运算符的结果都为假.IS NULL是真的,只有当所有的领域都是NULL.IS NOT NULL是真的,只有当所有的领域都是NOT NULL.对于介于两者之间的任何情况,两个运算符都返回false.
我确实有一些空字段,有些字段不是.我希望如果复合字段中的任何项不为null,则该字段将被视为非NULL,而不是当所有项都不为空时.除了检查每个字段之外还有什么方法吗?
Mur*_*nik 20
IS NULL并且也IS NOT NULL适用于复杂类型,所以这两个应该是合适的:
select * from bla where recipient is not null
select * from bla where recipient is null
Run Code Online (Sandbox Code Playgroud)
Erw*_*ter 14
要捕获不是复合值(行/记录)的所有字段都为NULL的情况:
SELECT *
FROM bla
WHERE NOT (recipient IS NULL);Run Code Online (Sandbox Code Playgroud)
<row-type> is NULL仅TRUE在所有字段都返回时返回NULL.
<row-type> is NOT NULL仅TRUE在所有字段都返回时返回NOT 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);
Run Code Online (Sandbox Code Playgroud)
结果:
recipient | all_null | all_notnull | some_notnull | some_null
-----------+----------+-------------+--------------+-----------
(foo,1) | f | t | t | f
(,2) | f | f | t | t
(,) | t | f | f | t
Run Code Online (Sandbox Code Playgroud)
有关: