Mysql
 sql >> Database >  >> RDS >> Mysql

Strano dappertutto

Aggiorna :Dopo un'ulteriore analisi e dispiegamento di > ALL di MySQL strana implementazione. Questa risposta dovrebbe essere considerata specifica per MySQL. Quindi, per ulteriore disclaimer, spiegazione sulla risposta qui relativa a > ALL non è applicabile ad altri RDBMS (a meno che non ci siano altri RDBMS che hanno copiato l'implementazione di MySQL). Traduzione interna da > ALL a un MAX costrutto, si applica solo a MySQL.

Questo:

select id from t1 where id > all (select id from t2); 

è semanticamente equivalente a:

select id from t1 where id > (select max(id) from t2); 

Poiché select max(id) from t2 restituisce 1, la seconda query si materializza in questo:

select id from t1 where id > 1

Ecco perché restituisce entrambi 10 e 2 dalla tabella t1

Uno dei casi in cui vengono applicate le regole NULL è quando usi NOT IN , un esempio:

DDL:

create table t1(id int);

insert into t1 values (10),(2);


create table t2(id int); 

insert into t2 values (0),(null),(1);

Domanda:

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;

Le ultime due query restituiscono 10 e 2 , mentre le prime due query restituiscono un insieme vuoto

Test dal vivo:http://www.sqlfiddle.com/#!2/82865/ 1

Spero che questi esempi cancellino la tua confusione con le regole NULL.

Riguardo a

Sql ottimizzato essendo questo:

select `test`.`t1`.`id` AS `id` from `test`.`t1` where <not>((`
test`.`t1`.`id` <= (select max(`test`.`t2`.`id`) from `test`.`t2`)))

Questo è davvero equivalente alla tua query originale:select id from t1 where id > all (select id from t2);

Il costrutto t1.field > all (select t2.field from t2) è solo uno zucchero sintattico per:

t1.field > (select max(t2.field) from t2)

Se applicherai il teorema di DeMorgan sull'SQL ottimizzato di MySql:

not (t1.id <= (select max(t2.id) from t2))

Ciò equivale a:

t1.id > (select max(t2.id) from t2)

Che a sua volta è equivalente allo zucchero sintattico ALL :

t1.id > ALL(select t2.id from t2)