Existují dvě varianty IN
výrazy:
expression IN (subquery)
expression IN (value [, ...])
Podobně dvě varianty s ANY
konstrukce:
expression operator ANY (subquery)
expression operator ANY (array expression)
Dílčí dotaz funguje pro obě techniky, ale na druhou tvar každého, IN
očekává seznam hodnot (jak je definováno ve standardním SQL), zatímco = ANY
očekává pole .
Který použít?
ANY
je pozdější, všestrannější doplněk, lze jej kombinovat s libovolným binárním operátorem vracejícím booleovskou hodnotu. IN
vyhoří na speciální případ ANY
. Ve skutečnosti je jeho druhá podoba interně přepsána:
IN
je přepsán s = ANY
NOT IN
je přepsán pomocí <> ALL
Zkontrolujte EXPLAIN
výstup pro jakýkoli dotaz, abyste se sami přesvědčili. To dokazuje dvě věci:
IN
nikdy nemůže být rychlejší než= ANY
.= ANY
nebude podstatně rychlejší.
O výběru by mělo rozhodnout, co je jednodušší poskytnout :seznam hodnot nebo pole (možná jako literál pole – jedna hodnota).
Pokud ID, která se chystáte předávat, pocházejí z databáze každopádně je mnohem efektivnější vybrat je přímo (poddotaz) nebo integrovat zdrojovou tabulku do dotazu pomocí JOIN
(jako komentář @mu).
Chcete-li předat dlouhý seznam hodnot od vašeho klienta a získejte nejlepší výkon , použijte pole, unnest()
a připojte se, nebo jej poskytněte jako tabulkový výraz pomocí VALUES
(jako komentář @PinnyM). Všimněte si však, že JOIN
zachová možné duplikáty v poskytnutém poli / set while IN
nebo = ANY
ne. Více:
- Optimalizace dotazu Postgres s velkým IN
V případě hodnot NULL NOT IN
je často špatná volba a NOT EXISTS
by bylo správné (a také rychlejší):
- Vyberte řádky, které se nenacházejí v jiné tabulce
Syntaxe pro = ANY
Pro výraz pole Postgres přijímá:
- konstruktor pole (pole je vytvořeno ze seznamu hodnot na straně Postgresu) ve tvaru:
ARRAY[1,2,3]
- nebo polový literál ve tvaru
'{1,2,3}'
.
Chcete-li se vyhnout neplatnému přetypování, můžete přetypovat explicitně:
ARRAY[1,2,3]::numeric[]
'{1,2,3}'::bigint[]
Související:
- PostgreSQL:Problém s předáním pole do procedury
- Jak předat pole vlastního typu funkci Postgres
Nebo můžete vytvořte funkci Postgres pomocí VARIADIC
parametr, který přebírá jednotlivé argumenty a tvoří z nich pole:
- Předání více hodnot v jednom parametru
Jak předat pole z Ruby?
Za předpokladu id
být integer
:
MyModel.where('id = ANY(ARRAY[?]::int[])', ids.map { |i| i})
Ale já jen fušuji do Ruby. @mu poskytuje podrobné pokyny v této související odpovědi:
- Odeslání pole hodnot do dotazu SQL v ruby?