sql >> Database >  >> RDS >> Mysql

Vreemd allemaal daar

Bijwerken :Na verdere analyse en ontvouwing van MySQL's > ALL vreemde uitvoering. Dit antwoord moet als MySQL-specifiek worden beschouwd. Dus voor verdere disclaimer, uitleg over het antwoord hier met betrekking tot > ALL is niet van toepassing op andere RDBMS'en (tenzij er andere RDBMS'en zijn die de MySQL-implementatie hebben gekopieerd). Interne vertaling van > ALL naar een MAX construct, is alleen van toepassing op MySQL.

Dit:

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

is semantisch gelijk aan:

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

Sinds select max(id) from t2 geeft 1 terug, de tweede vraag komt hierop neer:

select id from t1 where id > 1

Daarom retourneert het zowel 10 en 2 uit tabel t1

Een van de gevallen waarin NULL-regels worden toegepast, is wanneer u NOT IN . gebruikt , een voorbeeld:

DDL:

create table t1(id int);

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


create table t2(id int); 

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

Vraag:

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;

De laatste twee zoekopdrachten retourneren 10 en 2 , terwijl de eerste twee zoekopdrachten een lege set retourneren

Live-test:http://www.sqlfiddle.com/#!2/82865/ 1

Ik hoop dat deze voorbeelden je verwarring met NULL-regels uitwissen.

Betreffende

Geoptimaliseerde sql is dit:

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

Dat komt echt overeen met uw oorspronkelijke zoekopdracht:select id from t1 where id > all (select id from t2);

De constructie t1.field > all (select t2.field from t2) is slechts een syntactische suiker voor:

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

Als je de stelling van DeMorgan toepast op de geoptimaliseerde SQL door MySql:

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

Dat komt overeen met:

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

Wat op zijn beurt gelijk is aan de syntactische suiker ALL :

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


  1. Overschrijf de Query Optimizer voor uw T-SQL-joins met FORCEPLAN

  2. Wat is de snelste manier om de mediaan te berekenen?

  3. Permanente PHP-MySQL-verbindingen gebruiken om WordPress Blog uit te voeren

  4. MySQL DATE_ADD werkt niet