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

Wie verwendet man ANY statt IN in einer WHERE-Klausel mit Rails?

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?