Aktualizacja :Po dalszej analizie i rozwinięciu > ALL
MySQL dziwna realizacja. Ta odpowiedź powinna być traktowana jako specyficzna dla MySQL. Aby uzyskać dalsze wyłączenie odpowiedzialności, wyjaśnienie odpowiedzi tutaj dotyczące > ALL
nie ma zastosowania do innych systemów RDBMS (chyba że istnieją inne systemy RDBMS, które skopiowały implementację MySQL). Tłumaczenie wewnętrzne z > ALL
do MAX
konstrukcja, dotyczy tylko MySQL.
To:
select id from t1 where id > all (select id from t2);
jest semantycznie odpowiednikiem:
select id from t1 where id > (select max(id) from t2);
Ponieważ select max(id) from t2
zwraca 1, drugie zapytanie materializuje się do tego:
select id from t1 where id > 1
Dlatego zwraca oba 10
i 2
z tabeli t1
Jednym z przypadków, w których stosowane są reguły NULL, jest użycie NOT IN
, przykład:
DDL:
create table t1(id int);
insert into t1 values (10),(2);
create table t2(id int);
insert into t2 values (0),(null),(1);
Zapytanie:
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;
Ostatnie dwa zapytania zwracają 10
i 2
, podczas gdy pierwsze dwa zapytania zwracają pusty zestaw
Test na żywo:http://www.sqlfiddle.com/#!2/82865/ 1
Mam nadzieję, że te przykłady usuną twoje zamieszanie z zasadami NULL.
Odnośnie
Zoptymalizowany sql to:
select `test`.`t1`.`id` AS `id` from `test`.`t1` where <not>((`
test`.`t1`.`id` <= (select max(`test`.`t2`.`id`) from `test`.`t2`)))
To naprawdę odpowiada oryginalnemu zapytaniu:select id from t1 where id > all (select id from t2);
Konstrukcja t1.field > all (select t2.field from t2)
jest tylko cukrem składniowym dla:
t1.field > (select max(t2.field) from t2)
Jeśli zastosujesz twierdzenie DeMorgana na zoptymalizowanym SQL przez MySql:
not (t1.id <= (select max(t2.id) from t2))
To jest równoważne:
t1.id > (select max(t2.id) from t2)
Co z kolei jest równoważne cukierkowi składniowemu ALL
:
t1.id > ALL(select t2.id from t2)