В чем разница между Oracle SQL предложением "! = ANY (...)" и "not IN (...)" - PullRequest
0 голосов
/ 30 января 2020

Я использовал SQL запрос, подобный следующему:

select * from FOO_TABLE ft where ft.foo_field != any ('A','B','C');

Я думал, что результатом будут все записи, где поле foo_field не содержит 'A', 'B' или 'C' ( exclusive ), но в результате я получил все записи, в том числе записи с полем foo_field равным 'A' или 'B' или 'C'.

Чтобы избежать вышеуказанной проблемы, Я использовал:

select * from FOO_TABLE ft where ft.foo_field not in ('A','B','C');

Вышеприведенный запрос выполняется так, как я ожидал.

Я часто использую следующие запросы, чтобы сгенерировать обратный запрос выше (чтобы получить все записи, которые содержат 'A' или 'B' или 'C' - включительно ):

select * from FOO_TABLE ft where ft.foo_field = any ('A','B','C');

select * from FOO_TABLE ft where ft.foo_field in ('A','B','C');

Я думаю, что нет никаких различий в результатах между двумя запросами, которые я использую как включено . Это правда!?

Почему запросы " exclusive " имеют разное поведение?

Ответы [ 2 ]

1 голос
/ 30 января 2020

Я полагаю, что они эквивалентны, используя <> ALL, а не <> IN.

При рассмотрении таких конструкций в SQL, возможно, две наиболее важные ситуации, которые следует учитывать:

  • Пустые наборы (которые можно генерировать только с помощью подзапросов).
  • NULL-значения.

В обоих случаях in и = any ведут себя одинаково. Точно так же not in и <> all ведут себя одинаково.

Следует отметить, что <> all, вероятно, не работает должным образом, если в подзапросе есть NULL s. В этом случае он вообще ничего не возвращает. Вот почему я рекомендую NOT EXISTS более NOT IN.

1 голос
/ 30 января 2020

Я думаю, вы неправильно используете оператор NOT (!).

Как это работает:

"column_name = ANY (...)": значение должно совпадать одно или несколько значений в списке для оценки TRUE.

"column_name! = ANY (...)": значение не должно совпадать с одним или несколькими значениями в списке, чтобы иметь значение TRUE.

В вашем случае ваш столбец Допустим, значение 'A' совпадает с =ANY('A','B','C'), но в то же время, когда вы используете !=ANY('A','B','C'), оно также оценивается как TRUE как A!=B or A!=C.

Так что вы должны использовать column_name !=ALL('A','B','C') или используйте NOT column_name =ANY('A','B','C') следующим образом:

Либо используйте

select * from FOO_TABLE ft where NOT ft.foo_field = any ('A','B','C'); 
 -- see the keyword NOT before column name

или

select * from FOO_TABLE ft where ft.foo_field != ALL ('A','B','C');

Cheers !!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...