Was ist der Unterschied zwischen IN
und ANY
Operator in PostgreSQL?
Der Arbeitsmechanismus beider scheint der gleiche zu sein. Kann jemand dies mit einem Beispiel erklären?
Was ist der Unterschied zwischen IN
und ANY
Operator in PostgreSQL?
Der Arbeitsmechanismus beider scheint der gleiche zu sein. Kann jemand dies mit einem Beispiel erklären?
Antworten:
(Weder IN
noch ANY
ist ein "Operator". Ein "Konstrukt" oder "Syntaxelement".)
Logisch , zitiert das Handbuch :
IN
ist äquivalent zu= ANY
.
Es gibt jedoch zwei Syntaxvarianten von IN
und zwei Varianten von ANY
. Einzelheiten:
IN
Das Nehmen eines Sets entspricht dem = ANY
Nehmen eines Sets , wie hier gezeigt:
Aber die zweite Variante von jedem ist nicht gleichbedeutend mit der anderen. Die zweite Variante des ANY
Konstrukts verwendet ein Array (muss ein tatsächlicher Array-Typ sein), während die zweite Variante IN
eine durch Kommas getrennte Liste von Werten verwendet . Dies führt zu unterschiedlichen Einschränkungen bei der Übergabe von Werten und kann in besonderen Fällen auch zu unterschiedlichen Abfrageplänen führen:
=any()
aber verwendet mitin
ANY
ist vielseitigerDas ANY
Konstrukt ist weitaus vielseitiger, da es nicht nur mit verschiedenen Operatoren kombiniert werden kann =
. Beispiel:
SELECT 'foo' LIKE ANY('{FOO,bar,%oo%}');
Für eine große Anzahl von Werten ist die Bereitstellung eines Satzes für jeden Wert besser:
Verbunden:
"Suchen Sie Zeilen, in denen id
sich das angegebene Array befindet":
SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);
Inversion: "Zeilen suchen, die id
sich nicht im Array befinden":
SELECT * FROM tbl WHERE id <> ALL (ARRAY[1, 2]);
SELECT * FROM tbl WHERE id <> ALL ('{1, 2}'); -- equivalent array literal
SELECT * FROM tbl WHERE NOT (id = ANY ('{1, 2}'));
Alle drei gleichwertig. Der erste mit Array-Konstruktor , die anderen beiden mit Array-Literal . Der Datentyp kann eindeutig aus dem Kontext abgeleitet werden. Andernfalls kann eine explizite Besetzung erforderlich sein, wie z '{1,2}'::int[]
.
Zeilen mit übergeben id IS NULL
keinen dieser Ausdrücke. Um NULL
Werte zusätzlich aufzunehmen:
SELECT * FROM tbl WHERE (id = ANY ('{1, 2}')) IS NOT TRUE;
SELECT * from mytable where id in (1, 2, 3)
Dies bedeutet, dass immer dieselben Zeilen wie angezeigt werden SELECT * from mytable where id = ANY('{1, 2, 3}')
, auch wenn sie möglicherweise unterschiedliche Abfragepläne haben.
ANY
kann nicht mit dem !=
Bediener kombiniert werden. Ich denke nicht, dass es dokumentiert ist, aber es select * from foo where id != ANY (ARRAY[1, 2])
ist nicht dasselbe wie select * from foo where id NOT IN (1, 2)
. Funktioniert dagegen select * from foo where NOT (id = ANY (ARRAY[1, 2]))
wie erwartet.
ANY
kann mit dem !=
Operator kombiniert werden. Aber es steckt noch mehr dahinter. Ich habe oben ein Kapitel hinzugefügt. (Beachten Sie, dass dies <>
der Operator in Standard-SQL ist - obwohl dies !=
auch in Postgres akzeptiert wird.)
NULL
Werte enthält ? Würde WHERE id = ANY (ARRAY[1, 2]) OR id IS NULL;
genauso gut funktionieren?
(id = ...) IS NOT TRUE
funktioniert, weil id = ...
nur ausgewertet wird, TRUE
ob eine tatsächliche Übereinstimmung vorliegt . Ergebnisse FALSE
oder NULL
bestehen Sie unseren Test. Siehe: stackoverflow.com/a/23767625/939860 . Ihr hinzugefügter Ausdruck testet auf etwas anderes. Dies wäre gleichwertigWHERE id <> ALL (ARRAY[1, 2]) OR id IS NULL;
Es gibt zwei offensichtliche Punkte sowie die Punkte in der anderen Antwort:
Sie sind bei Verwendung von Unterabfragen genau gleichwertig:
SELECT * FROM table
WHERE column IN(subquery);
SELECT * FROM table
WHERE column = ANY(subquery);
Andererseits:
Nur der IN
Operator erlaubt eine einfache Liste:
SELECT * FROM table
WHERE column IN(… , … , …);
Die Annahme, dass sie genau gleich sind, hat mich mehrmals überrascht, als ich vergaß, dass ANY
dies mit Listen nicht funktioniert.