Istnieją dwa warianty IN
wyrażenia:
expression IN (subquery)
expression IN (value [, ...])
Podobnie dwa warianty z ANY
konstrukcja:
expression operator ANY (subquery)
expression operator ANY (array expression)
Podzapytanie działa dla obu technik, ale dla drugiej forma każdego, IN
oczekuje listy wartości (zgodnie z definicją w standardowym SQL), gdy = ANY
oczekuje tablicy .
Którego użyć?
ANY
jest późniejszym, bardziej wszechstronnym dodatkiem, można go łączyć z dowolnym operatorem binarnym zwracającym wartość logiczną. IN
spala się do specjalnego przypadku ANY
. W rzeczywistości jego druga forma została przepisana wewnętrznie:
IN
jest przepisany z = ANY
NOT IN
jest przepisany za pomocą <> ALL
Sprawdź EXPLAIN
dane wyjściowe dla dowolnego zapytania, aby zobaczyć na własne oczy. Dowodzi to dwóch rzeczy:
IN
nigdy nie może być szybszy niż= ANY
.= ANY
nie będzie znacznie szybszy.
O wyborze powinno decydować co jest łatwiejsze do dostarczenia :lista wartości lub tablica (ewentualnie jako literał tablicy - pojedyncza wartość).
Jeśli identyfikatory, które zamierzasz przekazać, pochodzą z bazy danych w każdym razie, znacznie wydajniej jest wybrać je bezpośrednio (podzapytanie) lub zintegrować tabelę źródłową z zapytaniem za pomocą JOIN
(jak skomentował @mu).
Aby przekazać długą listę wartości od swojego klienta i uzyskaj najlepszą wydajność , użyj tablicy, unnest()
i dołącz lub podaj jako wyrażenie tabelowe za pomocą VALUES
(jak skomentował @PinnyM). Pamiętaj jednak, że JOIN
zachowuje możliwe duplikaty w podanej tablicy / ustaw podczas IN
lub = ANY
nie rób. Więcej:
- Optymalizacja zapytania Postgres z dużym IN
W obecności wartości NULL, NOT IN
jest często złym wyborem i NOT EXISTS
miałby rację (i szybciej):
- Wybierz wiersze, których nie ma w innej tabeli
Składnia dla = ANY
Dla wyrażenia tablicowego Postgres akceptuje:
- konstruktor tablicowy (tablica jest skonstruowana z listy wartości po stronie Postgres) postaci:
ARRAY[1,2,3]
- lub literał tablicowy w postaci
'{1,2,3}'
.
Aby uniknąć rzutowania nieprawidłowych typów, możesz jawnie rzutować:
ARRAY[1,2,3]::numeric[]
'{1,2,3}'::bigint[]
Powiązane:
- PostgreSQL:problem z przekazywaniem tablicy do procedury
- Jak przekazać tablicę typów niestandardowych do funkcji Postgres
Albo możesz utwórz funkcję Postgres biorąc VARIADIC
parametr, który pobiera poszczególne argumenty i tworzy z nich tablicę:
- Przekazywanie wielu wartości w jednym parametrze
Jak przekazać tablicę z Rubiego?
Zakładając id
być integer
:
MyModel.where('id = ANY(ARRAY[?]::int[])', ids.map { |i| i})
Ale po prostu gram w Ruby. @mu zawiera szczegółowe instrukcje w tej powiązanej odpowiedzi:
- Wysyłasz tablicę wartości do zapytania sql w ruby?