PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Как да използвам ANY вместо IN в клауза WHERE с Rails?

Има два варианта на IN изрази:

  • expression IN (subquery)
  • expression IN (value [, ...])

По същия начин, два варианта с ANY конструкция:

  • expression operator ANY (subquery)
  • expression operator ANY (array expression)

Подзаявката работи и за двете техники, но за втората форма на всеки, IN очаква списък със стойности (както е дефинирано в стандартния SQL), докато = ANY очаква масив .

Кое да използвам?

ANY е по-късно, по-гъвкаво допълнение, може да се комбинира с всеки двоичен оператор, връщащ булева стойност. IN изгаря до специален случай на ANY . Всъщност втората му форма е пренаписана вътрешно:

IN се пренаписва с = ANY
NOT IN се пренаписва с <> ALL

Проверете EXPLAIN изход за всяка заявка, за да видите сами. Това доказва две неща:

  • IN никога не може да бъде по-бърз от = ANY .
  • = ANY няма да бъде значително по-бързо.

Изборът трябва да се реши откакво е по-лесно за предоставяне :списък със стойности или масив (евентуално като литерал на масива - една стойност).

Ако идентификаторите, които ще предадете, идватот БДа така или иначе е много по-ефективно да ги изберете директно (подзаявка) или да интегрирате изходната таблица в заявката с JOIN (харесвам @mu коментира).

За да преминете дълъг списък на стойностите от вашия клиент и получете най-доброто производителност , използвайте масив, unnest() и се присъединете или го предоставете като табличен израз с помощта на VALUES (като коментира @PinnyM). Но имайте предвид, че JOIN запазва възможни дубликати в предоставения масив / задайте докато IN или = ANY Недей. Още:

  • Оптимизиране на заявка в Postgres с голям IN

При наличие на NULL стойности, NOT IN често е грешен избор и NOT EXISTS би било правилно (и по-бързо):

  • Изберете редове, които не присъстват в друга таблица

Синтаксис за = ANY

За израза на масива Postgres приема:

  • конструктор на масив (масивът е конструиран от списък със стойности от страната на Postgres) във формата:ARRAY[1,2,3]
  • или литерал на масив от формата '{1,2,3}' .

За да избегнете невалидни прехвърляния на тип, можете да предавате изрично:

ARRAY[1,2,3]::numeric[]
'{1,2,3}'::bigint[]

Свързано:

  • PostgreSQL:Проблем с предаването на масив към процедура
  • Как да предам масив от персонализиран тип на функцията Postgres

Или можете създайте функция Postgres, като вземете VARIADIC параметър, който приема отделни аргументи и формира масив от тях:

  • Предаване на множество стойности в един параметър

Как да предам масива от Ruby?

Ако приемем id да бъде integer :

MyModel.where('id = ANY(ARRAY[?]::int[])', ids.map { |i| i})

Но аз просто се занимавам с Ruby. @mu предоставя подробни инструкции в този свързан отговор:

  • Изпращате ли масив от стойности към sql заявка в 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 в windows?

  2. Как да групирате по месеци в PostgreSQL

  3. Как да конвертирам цяло число в низ като част от заявка на PostgreSQL?

  4. Има ли някакъв начин да се изпълни заявка вътре в стойността на низа (като eval) в PostgreSQL?

  5. Разрешаване на нула в уникална колона