Актуализиране :При по-нататъшен анализ и разгръщане на > ALL
на MySQL странно изпълнение. Този отговор трябва да се счита за специфичен за MySQL. Така че за допълнително отказване от отговорност, обяснение на отговора тук относно > ALL
не е приложимо за други RDBMS (освен ако има други RDBMS, които са копирали MySQL реализацията). Вътрешен превод от > ALL
до MAX
construct, важи само за MySQL.
Това:
select id from t1 where id > all (select id from t2);
е семантично еквивалентен на:
select id from t1 where id > (select max(id) from t2);
Тъй като select max(id) from t2
връща 1, втората заявка се материализира до това:
select id from t1 where id > 1
Ето защо връща и двете 10
и 2
от таблица t1
Един от случаите, в които се прилагат NULL правила, е когато използвате NOT IN
, пример:
DDL:
create table t1(id int);
insert into t1 values (10),(2);
create table t2(id int);
insert into t2 values (0),(null),(1);
Запитване:
select * from t1 where id not in (select id from t2);
-- above is evaluated same as the following query, so the rules about null applies,
-- hence the above and following query will not return any record.
select * from t1 where id <> 0 and id <> null and id <> 1;
-- to eliminate null side-effect, do this:
select * from t1 where id not in (select id from t2 where id is not null);
-- which is equivalent to this:
select * from t1 where id <> 0 and id <> 1;
Последните две заявки връщат 10
и 2
, докато първите две заявки връщат празен набор
Тест на живо:http://www.sqlfiddle.com/#!2/82865/ 1
Надяваме се, че тези примери ще изтрият объркването ви с правилата NULL.
Относно
Оптимизиран sql е следният:
select `test`.`t1`.`id` AS `id` from `test`.`t1` where <not>((`
test`.`t1`.`id` <= (select max(`test`.`t2`.`id`) from `test`.`t2`)))
Това наистина е еквивалентно на оригиналната ви заявка:select id from t1 where id > all (select id from t2);
Конструкцията t1.field > all (select t2.field from t2)
е просто синтактична захар за:
t1.field > (select max(t2.field) from t2)
Ако ще приложите теоремата на ДеМорган върху оптимизирания SQL от MySql:
not (t1.id <= (select max(t2.id) from t2))
Това е еквивалентно на:
t1.id > (select max(t2.id) from t2)
Което от своя страна е еквивалентно на синтактичната захар ALL
:
t1.id > ALL(select t2.id from t2)