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?