Ich verwende den nativen Array-Typ von Postgres und versuche, die Datensätze zu finden, deren ID nicht in den Empfänger-IDs des Arrays enthalten ist.
Ich kann finden, wo sie IN sind:
SELECT COUNT(*) FROM messages WHERE (3 = ANY (recipient_ids))
Das funktioniert aber nicht:
SELECT COUNT(*) FROM messages WHERE (3 != ANY (recipient_ids))
SELECT COUNT(*) FROM messages WHERE (3 = NOT ANY (recipient_ids))
Was ist der richtige Weg, um auf diesen Zustand zu testen?
arrays
postgresql
user577808
quelle
quelle
WHERE 3 NOT IN recipient_ids
?text[]
undint[]
Array:select not(array[1,2,3] @> array[3]);
null
Spalte in einem Array enthalten ist oder nicht, wird immer Nein gesagt. Ich habe ungefähr 20 Minuten gebraucht, um mehrere enthaltene Methoden zu debuggen, um zu dem Schluss zu kommen, dass man nicht überprüfen kann, ob null in einem Array enthalten istAntworten:
Sie können immer negieren
WHERE (condition)
mitWHERE NOT (condition)
quelle
ANY
anstatt wechseln,IN
wenn Ihrerecipient_ids
Eingabeliste wächst: stackoverflow.com/questions/1009706/…Sie könnten es ein wenig umdrehen und sagen "3 ist nicht gleich allen IDs":
Aus dem feinen Handbuch :
quelle
any
in diesem Fall nicht funktioniertany
undall
auf postgres doc, das sagt: "x <> ANY (a,b,c)
ist gleichbedeutend mitx <> a OR <> b OR x <> c
". ref: postgresqltutorial.com/postgresql-any postgresqltutorial.com/postgresql-allAugmentierenden die
ALL/ANY
AntwortenIch bevorzuge alle Lösungen, die das Ergebnis verwenden
all
oder verwendenany
, um die zusätzlichen Hinweise zu schätzen (z. B. über NULL s). Als weitere Erweiterung finden Sie hier eine Möglichkeit, über diese Operatoren nachzudenken.Sie können sie als Kurzschlussbetreiber betrachten :
all(array)
Durchläuft alle Werte im Array und vergleicht sie mit dem angegebenen Wert mit dem angegebenen Operator. Sobald ein Vergleich ergibtfalse
, endet der Prozess mit false, andernfalls true. (Vergleichbar mit logischem Kurzschlussand
.)any(array)
Durchläuft alle Werte im Array und vergleicht sie mit dem angegebenen Wert mit dem angegebenen Operator. Sobald ein Vergleich ergibttrue
, endet der Prozess mit wahr, andernfalls falsch. (Vergleichbar mit logischem Kurzschlussor
.)Aus diesem Grund
3 <> any('{1,2,3}')
wird nicht das gewünschte Ergebnis erzielt: Der Prozess vergleicht 3 mit 1 für die Ungleichung, was wahr ist, und gibt sofort wahr zurück. Ein einzelner Wert im Array, der sich von 3 unterscheidet, reicht aus, um die gesamte Bedingung zu erfüllen. Die 3 an der letzten Array-Position ist prob. nie benutzt.3 <> all('{1,2,3}')
Auf der anderen Seite wird sichergestellt, dass nicht alle Werte gleich 3 sind. Es werden alle Vergleiche durchlaufen, die true ergeben, bis zu einem Element, das false ergibt (in diesem Fall das letzte), um false als Gesamtergebnis zurückzugeben. Das will das OP.quelle
not (3 = any(recipient_ids))
?quelle
3 <> ANY(ARRAY[1,2,3,4])
. Es hätte so funktionieren sollen: \ein Update:
ab postgres 9.3,
Sie können dies auch
NOT
zusammen mit dem@>
Operator (enthält) verwenden .IE.
SELECT COUNT(*) FROM "messages" WHERE NOT recipient_ids @> ARRAY[3];
quelle
Vorsicht vor NULL
Beide
ALL
:Und
ANY
:Würde funktionieren, solange
some_array
nicht null ist. Wenn das Array null sein könnte, müssen Sie es mit coalesce () berücksichtigen, zOder
Aus den Dokumenten :
quelle
Beachten Sie, dass die ANY / ALL-Operatoren nicht mit Array-Indizes funktionieren. Wenn Indizes im Auge behalten:
und das Negative:
Ein Index kann dann wie folgt erstellt werden:
quelle
&&
SELECT COUNT(*) FROM "messages" WHERE ARRAY[3] && recipient_ids
.