1 = ALL(arr) IS NULL AND 2 = ALL(arr) IS NULL
1
e 2
pode ser qualquer dois números distintos. Alternativas e desempenho
Existem muitos caminhos. Eu montei um caso de teste rápido:
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()
requer o Postgres 9.3 ou posterior.array_positions()
requer Postgres 9.5 ou posterior. chk_michael
é da resposta atualmente aceita por @michael
.As colunas estão na ordem de execução da expressão. Mais rápido primeiro.
Minhas verificações simples dominam o desempenho, com
array_remove()
próximo. O resto não consegue acompanhar. A matriz vazia de caso especial (
{}
) requer atenção. Defina o resultado esperado e escolha uma expressão de ajuste ou adicione uma verificação adicional. db<>fiddle aqui - com teste de desempenho
Antigo sqlfiddle
Como funciona?
A expressão
1 = ALL(arr)
rendimentos:TRUE
.. se todos os elementos forem 1
FALSE
.. se algum elemento for <> 1
(qualquer elemento que IS NOT NULL
)NULL
.. se pelo menos um elemento IS NULL
e nenhum elemento é <> 1
Então, se conhecemos um único elemento que não pode aparecer (imposto por um
CHECK
restrição), como -1
, podemos simplificar para:-1 = ALL(arr) IS NULL
Se qualquer número pode aparecer, verifique se há dois números distintos. O resultado só pode ser
NULL
para ambos se a matriz não contiver nada além de NULL
. Voilá.