sql >> Database teknologi >  >> RDS >> PostgreSQL

Hvordan bruger man ANY i stedet for IN i en WHERE-klausul med Rails?

Der er to varianter af IN udtryk:

  • expression IN (subquery)
  • expression IN (value [, ...])

Tilsvarende to varianter med ANY konstruktion:

  • expression operator ANY (subquery)
  • expression operator ANY (array expression)

En underforespørgsel virker for begge teknikker, men for den anden form af hver, IN forventer en liste over værdier (som defineret i standard SQL), mens = ANY forventer en array .

Hvilken skal man bruge?

ANY er en senere, mere alsidig tilføjelse, den kan kombineres med enhver binær operator, der returnerer en boolesk værdi. IN brænder ned til et særligt tilfælde af ANY . Faktisk er dens anden form omskrevet internt:

IN er omskrevet med = ANY
NOT IN er omskrevet med <> ALL

Tjek EXPLAIN output for enhver forespørgsel for selv at se. Dette beviser to ting:

  • IN kan aldrig være hurtigere end = ANY .
  • = ANY bliver ikke væsentligt hurtigere.

Valget bør afgøres af hvad der er nemmere at give :en liste over værdier eller et array (muligvis som array literal - en enkelt værdi).

Hvis de id'er, du vil videregive, kommer indefra DB alligevel er det meget mere effektivt at vælge dem direkte (underforespørgsel) eller integrere kildetabellen i forespørgslen med en JOIN (som @mu kommenterede).

At bestå en lang liste af værdier fra din klient og få den bedste ydelse , brug et array, unnest() og join, eller angiv det som tabeludtryk ved hjælp af VALUES (som @PinnyM kommenterede). Men bemærk, at en JOIN bevarer mulige duplikater i det angivne array / sæt mens IN eller = ANY lade være med. Mere:

  • Optimering af en Postgres-forespørgsel med en stor IN

I nærvær af NULL-værdier, NOT IN er ofte det forkerte valg og NOT EXISTS ville være rigtigt (og også hurtigere):

  • Vælg rækker, der ikke findes i en anden tabel

Syntaks for = ANY

For array-udtrykket accepterer Postgres:

  • en array-konstruktør (array er konstrueret ud fra en liste med værdier på Postgres-siden) af formen:ARRAY[1,2,3]
  • eller en array literal af formen '{1,2,3}' .

For at undgå ugyldige type casts, kan du caste eksplicit:

ARRAY[1,2,3]::numeric[]
'{1,2,3}'::bigint[]

Relateret:

  • PostgreSQL:Problem med at overføre array til procedure
  • Sådan overfører du tilpasset type-array til Postgres-funktionen

Eller du kunne opret en Postgres-funktion med en VARIADIC parameter, som tager individuelle argumenter og danner en matrix ud fra dem:

  • Videregivelse af flere værdier i en enkelt parameter

Hvordan sender man arrayet fra Ruby?

Forudsat id at være integer :

MyModel.where('id = ANY(ARRAY[?]::int[])', ids.map { |i| i})

Men jeg tumler bare med Ruby. @mu giver detaljerede instruktioner i dette relaterede svar:

  • Sender du matrix af værdier til en sql-forespørgsel i ruby?



  1. Sådan omdannes en database i MySQL Workbench

  2. Sådan opretter du pivottabel i PostgreSQL

  3. Kan ikke oprette forbindelse til MySQL fra Java:NullPointerException inde i MySQL-driverforbindelseslogikken

  4. Henter alle objektprivilegier for specifik rolle