Ist eine Postgres-Methode die Kombination IS DISTINCT FROM
mit ANY
oder eine andere nette Methode, um das gleiche Ergebnis zu erzielen ?
select count(*)
from (select 'A' foo union all select 'Z' union all select null) z
where foo <> any(array[null, 'A']);
count
-------
1
(1 row)
select count(*)
from (select 'A' foo union all select 'Z' union all select null) z
where foo is distinct from any(array[null, 'A']);
ERROR: syntax error at or near "any"
LINE 3: where foo is distinct from any(array[null, 'A']);
^
quelle
IS DISTINCT FROM
Bediener sein? Scheint eher eine technische Einschränkung des Parsers zu sein als ein semantisches Problem.Operator
Dies baut auf @ Daniel's cleverem Operator auf .
Erstellen Sie dabei die Funktions- / Operatorkombination mit polymorphen Typen . Dann funktioniert es für jeden Typ - genau wie das Konstrukt.
Und mach die Funktion
IMMUTABLE
.Eine Schnellsuche mit symbolhound war leer, sodass der Operator
<!>
in keinem der Module verwendet zu werden scheint.Wenn Sie diesen Operator häufig verwenden, können Sie ihn dem Abfrageplaner näher bringen ( wie in einem Kommentar unter losthorse vorgeschlagen ). Für den Anfang können Sie die Klauseln
COMMUTATOR
und hinzufügenNEGATOR
, um das Abfrageoptimierungsprogramm zu unterstützen. Ersetzen SieCREATE OPERATOR
von oben mit diesem:Und füge hinzu:
Die zusätzlichen Klauseln helfen jedoch nicht im vorliegenden Anwendungsfall, und einfache Indizes werden weiterhin nicht verwendet. Um dies zu erreichen, ist es viel ausgefeilter. (Ich habe es nicht versucht.) Weitere Informationen finden Sie im Kapitel "Informationen zur Bedieneroptimierung" im Handbuch.
Testfall
Der Testfall in der Frage kann nur erfolgreich sein, wenn alle Werte im Array identisch sind. Für das Array in der Frage (
'{null,A}'::text[]
) ist das Ergebnis immer WAHR. Ist das beabsichtigt? Ich habe einen weiteren Test für "IS DISTINCT FROM ALL" hinzugefügt:Alternative mit Standardbetreibern
kann fast übersetzt werden
foo = ALL (test_arr)
ergibt ...TRUE
..wenn alle Elemente sindfoo
FALSE
..wenn irgendeinNOT NULL
Element ist<> foo
NULL
..wenn mindestens ein ElementIS NULL
und kein Element ist<> foo
Der verbleibende Eckfall ist also wo
-
foo IS NULL
- und
test_arr
besteht nur ausNULL
Elementen.Wenn einer von beiden ausgeschlossen werden kann, sind wir fertig. Verwenden Sie daher den einfachen Test, wenn
- die Spalte definiert ist
NOT NULL
.- oder Sie wissen, dass das Array niemals alle NULL-Werte enthält.
Sonst zusätzlich testen:
Wo
'A'
und'B'
kann keine unterschiedlichen Werte. Erklärung und Alternativen unter dieser verwandten Frage zu SO:Ist Array alle NULLs in PostgreSQL
Noch einmal, wenn Sie wissen , über einen beliebigen Wert, der in nicht existieren kann
test_arr
zum Beispiel die leere Zeichenkette''
, können Sie noch vereinfachen:Hier ist eine vollständige Testmatrix, um nach allen Kombinationen zu suchen:
Dies ist etwas ausführlicher als Andriys
EXCEPT
Lösung , aber wesentlich schneller.quelle
OPERATOR
sollte dieCOMMUTATOR
(undNEGATOR
vielleicht mit der inversenIS NOT DISTINCT FROM
Operator) Klausel geliefert werden? postgresql.org/docs/current/static/xoper-optimization.htmlapp_status <!> any(array[3,6])
. Auf Datensätze hat dies leider keine Auswirkung. Funktioniert es mit ganzen Zahlen?