sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Es la matriz todos los NULL en PostgreSQL?

1 = ALL(arr) IS NULL AND 2 = ALL(arr) IS NULL

1 y 2 puede ser cualquiera dos números distintos.

Alternativas y rendimiento

Hay muchas maneras. Monté un caso de prueba rápida:

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() requiere Postgres 9.3 o posterior.
array_positions() requiere Postgres 9.5 o posterior.

chk_michael es de la respuesta actualmente aceptada por @michael .
Las columnas están en orden de ejecución de la expresión. El más rápido primero.
Mis controles simples dominan el rendimiento, con array_remove() Siguiente. El resto no puede seguir el ritmo.

La matriz vacía de caso especial ({} ) requiere atención. Defina el resultado esperado y elija una expresión adecuada o agregue una verificación adicional.

db<>fiddle aquí - con prueba de rendimiento
Antiguo sqlfiddle

¿Cómo funciona?

La expresión 1 = ALL(arr) rendimientos:

TRUE .. si todos los elementos son 1
FALSE .. si algún elemento es <> 1 (cualquier elemento que IS NOT NULL )
NULL .. si al menos un elemento IS NULL y ningún elemento es <> 1

Entonces, si conocemos un solo elemento que no puede aparecer (aplicado por un CHECK restricción), como -1 , podemos simplificar a:

-1 = ALL(arr) IS NULL

Si cualquiera número puede aparecer, compruebe si hay dos números distintos. El resultado solo puede ser NULL para ambos si la matriz no contiene nada más que NULL . Voilá.