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:
INnikdy nemůže být rychlejší než= ANY.= ANYnebude 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?