Es gibt zwei Varianten von IN
Ausdrücke:
expression IN (subquery)
expression IN (value [, ...])
Ebenso zwei Varianten mit dem ANY
konstruieren:
expression operator ANY (subquery)
expression operator ANY (array expression)
Eine Unterabfrage funktioniert für beide Techniken, aber für die zweite Form von jedem, IN
erwartet eine Werteliste (wie in Standard-SQL definiert) während = ANY
erwartet ein Array .
Welche verwenden?
ANY
ist eine spätere, vielseitigere Ergänzung, die mit jedem binären Operator kombiniert werden kann, der einen booleschen Wert zurückgibt. IN
verbrennt auf einen Sonderfall von ANY
. Tatsächlich wird die zweite Form intern umgeschrieben:
IN
wird mit = ANY
umgeschrieben NOT IN
wird mit <> ALL
umgeschrieben
Prüfen Sie EXPLAIN
Ausgabe für jede Abfrage, um es selbst zu sehen. Dies beweist zwei Dinge:
IN
kann nie schneller sein als= ANY
.= ANY
wird nicht wesentlich schneller sein.
Die Wahl sollte danach erfolgen, was einfacher bereitzustellen ist :eine Liste von Werten oder ein Array (möglicherweise als Array-Literal - ein einzelner Wert).
Wenn die IDs, die Sie übergeben werden, aus der Datenbank stammen Auf jeden Fall ist es viel effizienter, sie direkt auszuwählen (Unterabfrage) oder die Quelltabelle mit einem JOIN
in die Abfrage zu integrieren (wie @mu kommentiert).
Um eine lange Liste weiterzugeben der Werte Ihres Kunden und erhalten Sie die beste Leistung , verwenden Sie ein Array, unnest()
und verbinden, oder mit VALUES
als Tabellenausdruck bereitstellen (wie @PinnyM kommentierte). Aber beachten Sie, dass ein JOIN
bewahrt mögliche Duplikate im bereitgestellten Array / set while IN
oder = ANY
unterlassen Sie. Mehr:
- Optimieren einer Postgres-Abfrage mit einem großen IN
Bei Vorhandensein von NULL-Werten NOT IN
ist oft die falsche Wahl und NOT EXISTS
wäre richtig (und auch schneller):
- Wählen Sie Zeilen aus, die in keiner anderen Tabelle vorhanden sind
Syntax für = ANY
Für den Array-Ausdruck akzeptiert Postgres:
- ein Array-Konstruktor (Array wird aus einer Liste von Werten auf der Postgres-Seite erstellt) der Form:
ARRAY[1,2,3]
- oder ein Array-Literal der Form
'{1,2,3}'
.
Um ungültige Typumwandlungen zu vermeiden, können Sie explizit umwandeln:
ARRAY[1,2,3]::numeric[]
'{1,2,3}'::bigint[]
Verwandte:
- PostgreSQL:Problem beim Übergeben des Arrays an die Prozedur
- So übergeben Sie ein benutzerdefiniertes Typarray an die Postgres-Funktion
Oder Sie könnten Erstellen Sie eine Postgres-Funktion, die einen VARIADIC
verwendet Parameter, der einzelne Argumente nimmt und daraus ein Array bildet:
- Mehrere Werte in einem einzigen Parameter übergeben
Wie übergebe ich das Array von Ruby?
Angenommen id
integer
sein :
MyModel.where('id = ANY(ARRAY[?]::int[])', ids.map { |i| i})
Aber ich versuche mich nur in Ruby. @mu bietet detaillierte Anweisungen in dieser verwandten Antwort:
- Senden eines Arrays von Werten an eine SQL-Abfrage in Ruby?