sql >> Base de Datos >  >> RDS >> Mysql

Extraño todo en donde

Actualizar :Tras un análisis más profundo y desarrollo de > ALL de MySQL implementación extraña. Esta respuesta debe considerarse específica de MySQL. Entonces, para un descargo de responsabilidad adicional, la explicación de la respuesta aquí con respecto a > ALL no es aplicable a otros RDBMS (a menos que haya otros RDBMS que hayan copiado la implementación de MySQL). Traducción interna de > ALL a un MAX construcción, se aplica solo a MySQL.

esto:

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

es semánticamente equivalente a:

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

Desde select max(id) from t2 devuelve 1, la segunda consulta se materializa en esto:

select id from t1 where id > 1

Es por eso que devuelve tanto 10 y 2 de la tabla t1

Uno de los casos en los que se aplican reglas NULL es cuando usa NOT IN , un ejemplo:

DDL:

create table t1(id int);

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


create table t2(id int); 

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

Consulta:

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;

Las últimas dos consultas devuelven 10 y 2 , mientras que las dos primeras consultas devuelven un conjunto vacío

Prueba en vivo:http://www.sqlfiddle.com/#!2/82865/ 1

Espero que estos ejemplos borre su confusión con las reglas NULL.

En cuanto a

Sql optimizado siendo este:

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

Eso es realmente equivalente a su consulta original:select id from t1 where id > all (select id from t2);

La construcción t1.field > all (select t2.field from t2) es solo un azúcar sintáctico para:

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

Si aplicará el teorema de DeMorgan en el SQL optimizado por MySql:

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

Eso es equivalente a:

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

Que a su vez es equivalente al azúcar sintáctico ALL :

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