PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak używać ANY zamiast IN w klauzuli WHERE w Railsach?

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?



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL + Hibernate + Spring automatyczne tworzenie bazy danych

  2. Dział ( / ) nie daje mojej odpowiedzi w postgresql

  3. PostgreSQL 9.3:Dynamiczna tabela przestawna

  4. Czy kolejność tabel w złączeniu ma znaczenie, gdy używane są złączenia LEWE (zewnętrzne)?

  5. Co zrobić z wartościami null podczas modelowania i normalizacji?