Mysql
 sql >> Base de données >  >> RDS >> Mysql

Bizarre partout

Mettre à jour  :Après une analyse plus approfondie et le déploiement de > ALL de MySQL mise en œuvre étrange. Cette réponse doit être considérée comme spécifique à MySQL. Donc, pour plus d'avertissement, explication sur la réponse ici concernant > ALL n'est pas applicable aux autres SGBDR (sauf s'il existe d'autres SGBDR qui ont copié l'implémentation de MySQL). Traduction interne de > ALL à un MAX construction, s'applique uniquement à MySQL.

Ceci :

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

est sémantiquement équivalent à :

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

Depuis select max(id) from t2 renvoie 1, la deuxième requête se matérialise par ceci :

select id from t1 where id > 1

C'est pourquoi il renvoie à la fois 10 et 2 du tableau t1

L'une des instances où les règles NULL sont appliquées est lorsque vous utilisez NOT IN , un exemple :

DDL :

create table t1(id int);

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


create table t2(id int); 

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

Requête :

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;

Les deux dernières requêtes renvoient 10 et 2 , alors que les deux premières requêtes renvoient un ensemble vide

Test en direct :http://www.sqlfiddle.com/#!2/82865/ 1

J'espère que ces exemples effacent votre confusion avec les règles NULL.

Concernant

SQL optimisé étant ceci :

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

C'est vraiment équivalent à votre requête d'origine :select id from t1 where id > all (select id from t2);

La construction t1.field > all (select t2.field from t2) n'est qu'un sucre syntaxique pour :

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

Si vous appliquez le théorème de DeMorgan sur le SQL optimisé par MySql :

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

Cela équivaut à :

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

Qui à son tour équivaut au sucre syntaxique ALL :

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