1 = ALL(arr) IS NULL AND 2 = ALL(arr) IS NULL
1
and 2
can be any两个不同的数字。
替代方案和性能
有很多方法。我组装了一个快速测试用例:
SELECT arr::text
, -1 = ALL(arr) IS NULL AS xsimple
, 1 = ALL(arr) IS NULL AND 2 = ALL(arr) IS NULL AS simple
, array_remove(arr, NULL) = '{}' AS array_rem
, cardinality(array_positions(arr, NULL))
= cardinality(arr) AS array_pos
, TRUE = ALL (SELECT unnest(arr) IS NULL) AS michael
, (SELECT bool_and(e IS NULL) FROM unnest(arr) e) AS bool_and
, NOT EXISTS (SELECT unnest(arr) EXCEPT SELECT null) AS exist
FROM (
VALUES
('{1,2,NULL,3}'::int[])
, ('{1,1,1}')
, ('{2,2,2}')
, ('{NULL,NULL,NULL}')
, ('{}'::int[])
) t(arr);
arr | xsimple | simple | array_rem | array_pos | michael | bool_and | exist
------------------+---------+--------+-----------+-----------+---------+----------+-------
{1,2,NULL,3} | f | f | f | f | f | f | f
{1,1,1} | f | f | f | f | f | f | f
{2,2,2} | f | f | f | f | f | f | f
{NULL,NULL,NULL} | t | t | t | t | t | t | t
{} | f | f | t | t | t | | t
array_remove()需要 Postgres 9.3 或更高版本。
array_positions()需要 Postgres 9.5 或更高版本。
chk_michael
是来自目前接受@michael 的答案.
这些列按表达式的执行顺序排列。最快的第一。
我的简单检查主导了性能,array_remove()
下一个。其余的都跟不上。
The 特殊情况空数组({}
)需要注意。定义预期结果并选择合适的表达式或添加额外的检查。
db<>fiddle here - with performance test
Old sqlfiddle
它是如何工作的?
表达方式1 = ALL(arr)
yields:
TRUE
..如果所有元素都是1
FALSE
..如果有任何元素<> 1
(任何元素IS NOT NULL
)
NULL
..如果至少有一个元素IS NULL
并且没有元素是<> 1
所以,如果我们知道一个元素cannot出现(由CHECK
约束),例如-1
,我们可以简化为:
-1 = ALL(arr) IS NULL
If any可以显示号码,检查是否有两个不同的号码。结果只能是NULL
对于两者,如果数组仅包含NULL
. Voilá.