Det finns två varianter av IN
uttryck:
expression IN (subquery)
expression IN (value [, ...])
På samma sätt två varianter med ANY
konstruera:
expression operator ANY (subquery)
expression operator ANY (array expression)
En underfråga fungerar för båda teknikerna, men för den andra form av varje, IN
förväntar sig en värdelista (enligt definition i standard SQL) medan = ANY
förväntar sig en array .
Vilket ska jag använda?
ANY
är ett senare, mer mångsidigt tillägg, det kan kombineras med vilken binär operator som helst som returnerar ett booleskt värde. IN
brinner ner till ett specialfall av ANY
. Faktum är att dess andra form är omskriven internt:
IN
skrivs om med = ANY
NOT IN
skrivs om med <> ALL
Kontrollera EXPLAIN
utgång för alla frågor att se själv. Detta bevisar två saker:
IN
kan aldrig vara snabbare än= ANY
.= ANY
kommer inte att bli avsevärt snabbare.
Valet bör avgöras av vad som är lättare att tillhandahålla :en lista med värden eller en array (möjligen som array literal - ett enda värde).
Om ID:n du ska skicka kommer inifrån DB hur som helst, det är mycket effektivare att välja dem direkt (underfråga) eller integrera källtabellen i frågan med en JOIN
(gilla @mu kommenterade).
För att klara en lång lista av värderingar från din kund och få bästa prestanda , använd en array, unnest()
och gå med, eller tillhandahåll det som tabelluttryck med VALUES
(som @PinnyM kommenterade). Men observera att en JOIN
bevarar möjliga dubbletter i den angivna arrayen/uppsättningen medan IN
eller = ANY
låt bli. Mer:
- Optimera en Postgres-fråga med ett stort IN
I närvaro av NULL-värden, NOT IN
är ofta fel val och NOT EXISTS
skulle vara rätt (och snabbare också):
- Välj rader som inte finns i andra tabeller
Syntax för = ANY
För matrisuttrycket accepterar Postgres:
- en matriskonstruktor (matrisen är konstruerad från en lista med värden på Postgres-sidan) av formen:
ARRAY[1,2,3]
- eller en array literal av formen
'{1,2,3}'
.
För att undvika ogiltiga casts kan du casta uttryckligen:
ARRAY[1,2,3]::numeric[]
'{1,2,3}'::bigint[]
Relaterat:
- PostgreSQL:Problem med att skicka array till proceduren
- Hur man skickar anpassad typarray till Postgres-funktionen
Eller du kunde skapa en Postgres-funktion med en VARIADIC
parameter, som tar individuella argument och bildar en array av dem:
- Att skicka flera värden i en enda parameter
Hur skickar man arrayen från Ruby?
Förutsatt id
vara integer
:
MyModel.where('id = ANY(ARRAY[?]::int[])', ids.map { |i| i})
Men jag pysslar bara med Ruby. @mu ger detaljerade instruktioner i detta relaterade svar:
- Skickar du array av värden till en SQL-fråga i ruby?