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

Underligt alle steder

Opdater :Ved yderligere analyse og udfoldelse af MySQL's > ALL mærkelig implementering. Dette svar skal betragtes som MySQL-specifikt. Så for yderligere ansvarsfraskrivelse, forklaring på svar her vedrørende > ALL er ikke gældende for andre RDBMS'er (medmindre der er andre RDBMS'er, der kopierede MySQL-implementering). Intern oversættelse fra > ALL til en MAX konstruktion, gælder kun for MySQL.

Dette:

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

er semantisk ækvivalent med:

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

Siden select max(id) from t2 returnerer 1, den anden forespørgsel materialiseres til dette:

select id from t1 where id > 1

Det er derfor, det returnerer både 10 og 2 fra tabel t1

Et af de tilfælde, hvor NULL-regler anvendes, er når du bruger NOT IN , et eksempel:

DDL:

create table t1(id int);

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


create table t2(id int); 

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

Forespørgsel:

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 sidste to forespørgsler returnerer 10 og 2 , hvorimod de to første forespørgsler returnerer tomt sæt

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

Håber disse eksempler sletter din forvirring med NULL-regler.

Angående

Optimeret sql er dette:

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

Det svarer virkelig til din oprindelige forespørgsel:select id from t1 where id > all (select id from t2);

Konstruktionen t1.field > all (select t2.field from t2) er kun et syntaktisk sukker for:

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

Hvis du vil anvende DeMorgan-sætningen på den optimerede SQL af MySql:

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

Det svarer til:

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

Hvilket igen svarer til det syntaktiske sukker ALL :

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


  1. Hvordan databaser understøtter e-handelsvirksomheder

  2. Afrunding til 2 decimaler i SQL

  3. Gå til start testdrevet databaseudvikling (TDDD)

  4. Brug af en Join med grupperede datarækker