PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Ist ein Array aus NULLen in PostgreSQL

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

1 und 2 kann beliebig sein zwei unterschiedliche Nummern.

Alternativen und Leistung

Es gibt viele Wege. Ich habe einen schnellen Testfall zusammengestellt:

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() erfordert Postgres 9.3 oder höher.
array_positions() erfordert Postgres 9.5 oder höher.

chk_michael stammt aus der aktuell akzeptierten Antwort von @michael .
Die Spalten sind in der Reihenfolge der Leistung des Ausdrucks angeordnet. Am schnellsten zuerst.
Meine einfachen Prüfungen dominieren die Leistung, mit array_remove() nächste. Der Rest kann nicht mithalten.

Der Sonderfall leeres Array ({} ) erfordert Aufmerksamkeit. Definieren Sie das erwartete Ergebnis und wählen Sie entweder einen passenden Ausdruck oder fügen Sie eine zusätzliche Prüfung hinzu.

db<>fiddle hier - mit Leistungstest
Altes sqlfiddle

Wie funktioniert es?

Der Ausdruck 1 = ALL(arr) ergibt:

TRUE .. wenn alle Elemente 1 sind
FALSE .. wenn irgendein Element <> 1 ist (jedes Element, das IS NOT NULL ist )
NULL .. wenn mindestens ein Element IS NULL und kein Element ist <> 1

Wenn wir also ein einzelnes Element kennen, das nicht kann auftauchen (durch CHECK erzwungen Einschränkung), wie -1 , können wir vereinfachen zu:

-1 = ALL(arr) IS NULL

Falls irgendwelche Nummer angezeigt werden kann, suchen Sie nach zwei unterschiedlichen Nummern. Das Ergebnis kann nur NULL sein für beide, wenn das Array nichts als NULL enthält . Voilá.