Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Estranho em todos os lugares


Atualizar :Após análise e desdobramento de > ALL do MySQL implementação ímpar. Esta resposta deve ser considerada como específica do MySQL. Portanto, para mais isenção de responsabilidade, explicação sobre a resposta aqui sobre > ALL não é aplicável a outros RDBMSes (a menos que existam outros RDBMSes que copiaram a implementação do MySQL). Tradução interna de > ALL para um MAX construção, aplica-se apenas ao MySQL.

Este:
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); 

Como select max(id) from t2 retorna 1, a segunda consulta se materializa para isso:
select id from t1 where id > 1

É por isso que ele retorna tanto 10 e 2 da tabela t1

Uma das instâncias em que as regras NULL estão sendo aplicadas é quando você usa NOT IN , um exemplo:

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;

As duas últimas consultas retornam 10 e 2 , enquanto as duas primeiras consultas retornam um conjunto vazio

Teste ao vivo:http://www.sqlfiddle.com/#!2/82865/ 1

Espero que esses exemplos apaguem sua confusão com as regras NULL.

Em relação a

SQL otimizado sendo este:
select `test`.`t1`.`id` AS `id` from `test`.`t1` where <not>((`
test`.`t1`.`id` <= (select max(`test`.`t2`.`id`) from `test`.`t2`)))

Isso é realmente equivalente à sua consulta original:select id from t1 where id > all (select id from t2);

A construção t1.field > all (select t2.field from t2) é apenas um açúcar sintático para:
t1.field > (select max(t2.field) from t2)

Se você aplicar o teorema de DeMorgan no SQL otimizado pelo MySql:
not (t1.id <= (select max(t2.id) from t2))

Isso é equivalente a:
t1.id > (select max(t2.id) from t2)

Que por sua vez é equivalente ao açúcar sintático ALL :
t1.id > ALL(select t2.id from t2)