Почему количество выбранных кортежей варьируется в этих запросах - PullRequest
0 голосов
/ 24 сентября 2019

Я новичок в СУБД и SQL.Практикуя некоторые основные вопросы, я столкнулся с этим сомнением.Надеюсь, я смогу объяснить это успешно.

Предположим, что результат этого запроса нулевой: select * from table2 b where b.age>50; то есть возраст в таблице2 не превышает 50.

Почему запрос похож на select * from table1 a where a.age> all(select b.age from table2 b where b.age>50); выберите все кортежи в table1

Принимая во внимание, что запрос: select * from table1 a where a.age> any(select b.age from table2 b where b.age>50); выбирает 0 кортежей.

Пожалуйста, объясните логику, стоящую за ними (вероятно, с точки зрения интерпретатора SQL)

Ответы [ 2 ]

1 голос
/ 24 сентября 2019

Это задокументированное поведение .

Для ANY (или SOME) с добавлением акцента:

Сравнивает значение для каждогозначение в списке или возвращается по запросу.Должно предшествовать =,! =,>, <, <=,> =.За ним может следовать любое выражение или подзапрос, который возвращает одно или несколько значений.

Оценивается как FALSE, если запрос не возвращает строк.

Для ALL:

Сравнивает значение с каждым значением в списке или возвращается по запросу.Должно предшествовать =,! =,>, <, <=,> =.За ним может следовать любое выражение или подзапрос, который возвращает одно или несколько значений.

Оценивается как ИСТИНА, если запрос не возвращает строк.

По мере получения подзапросабез строк, поэтому ожидается, что версия ANY оценивается как ложная, поскольку

select * from table1 a where a.age> all(select b.age from table2 b where b.age>50);

оценивается как (игнорируя то, что вы не можете явно указать true / false):

select * from table1 a where false; -- or more legally: where 1=0 

и т. Д. Не возвращает строк;

Но условие ALL оценивается как true, поскольку

select * from table1 a where true; -- or more legally: where 1=1

и поэтому возвращает все строки.

1 голос
/ 24 сентября 2019

select * from table1 a where a.age > all(select b.age from table2 b where b.age>50);

Ваш первый запрос берет каждую запись из table1, а затем проверяет, превышает ли age все результаты подзапроса.Поскольку подзапрос не имеет результатов, это всегда верно.

select * from table1 a where a.age > any(select b.age from table2 b where b.age>50);

Ваш второй запрос берет каждую запись из table1, а затем проверяет, больше ли ageчем любой результат подзапроса.Поскольку подзапрос не имеет результатов, это никогда не соответствует действительности.

...