У чому різниця між оператором IN
і ANY
PostgreSQL?
Здається, механізм роботи обох однаковий. Хтось може пояснити це прикладом?
У чому різниця між оператором IN
і ANY
PostgreSQL?
Здається, механізм роботи обох однаковий. Хтось може пояснити це прикладом?
Відповіді:
(Ні, IN
ні ANY
"оператор". "Конструкція" або "елемент синтаксису".)
Логічно , цитуючи посібник :
IN
еквівалентно= ANY
.
Але є два варіанти синтаксису з IN
і два варіанти ANY
. Деталі:
IN
взяти набір еквівалентно = ANY
прийому набору , як показано тут:
Але другий варіант кожного не рівнозначний іншому. Другий варіант ANY
конструкції займає масив (повинен бути фактичним типом масиву), тоді як другий варіант IN
має перелік значень, розділених комами . Це призводить до різних обмежень у передачі значень, а також може призвести до різних планів запитів у особливих випадках:
=any()
але використовується зin
ANY
є більш універсальнимANY
Конструкція є набагато більш універсальним, так як він може бути об'єднаний з різними операторами, а не тільки =
. Приклад:
SELECT 'foo' LIKE ANY('{FOO,bar,%oo%}');
Для великої кількості значень найкраще забезпечувати задану шкалу для кожного:
Пов'язані:
"Знайти рядки, де id
знаходиться у даному масиві":
SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);
Інверсія: «Знайти рядки , в яких id
є НЕ в масиві»:
SELECT * FROM tbl WHERE id <> ALL (ARRAY[1, 2]);
SELECT * FROM tbl WHERE id <> ALL ('{1, 2}'); -- equivalent array literal
SELECT * FROM tbl WHERE NOT (id = ANY ('{1, 2}'));
Усі три еквіваленти. Перший з конструктором масиву , інші два з літералом масиву . Тип даних може бути отриманий з контексту однозначно. В іншому випадку може знадобитися чіткий ролик, наприклад '{1,2}'::int[]
.
Рядки з id IS NULL
не містять жодного з цих виразів. Щоб NULL
додатково включити значення:
SELECT * FROM tbl WHERE (id = ANY ('{1, 2}')) IS NOT TRUE;
SELECT * from mytable where id in (1, 2, 3)
завжди буде мати однакові рядки SELECT * from mytable where id = ANY('{1, 2, 3}')
, навіть якщо вони потенційно можуть мати різні плани запитів.
ANY
не може поєднуватися з !=
оператором. Я не думаю, що це документально підтверджено, але select * from foo where id != ANY (ARRAY[1, 2])
це не те саме, що select * from foo where id NOT IN (1, 2)
. З іншого боку, select * from foo where NOT (id = ANY (ARRAY[1, 2]))
працює як очікувалося.
ANY
може поєднуватися з !=
оператором. Але в цьому є більше. Я додав розділ вище. (Зауважте, що <>
це оператор у стандартному SQL - хоча !=
це прийнято також і в Postgres.)
NULL
значення? Працювало б WHERE id = ANY (ARRAY[1, 2]) OR id IS NULL;
так само добре?
(id = ...) IS NOT TRUE
працює, тому що id = ...
оцінює лише те, TRUE
чи є фактична відповідність. Результати FALSE
або NULL
пройти тест. Дивіться: stackoverflow.com/a/23767625/939860 . Ваш доданий тест на експресію на щось інше. Це було б рівнозначноWHERE id <> ALL (ARRAY[1, 2]) OR id IS NULL;
Є два очевидних моменти, а також пункти в іншій відповіді:
Вони точно еквівалентні при використанні підзапитів:
SELECT * FROM table
WHERE column IN(subquery);
SELECT * FROM table
WHERE column = ANY(subquery);
З іншої сторони:
Тільки IN
оператор дозволяє простий список:
SELECT * FROM table
WHERE column IN(… , … , …);
Якщо припустити, що вони абсолютно однакові, мене кілька разів зловило, забувши, що ANY
не працює зі списками.