简体   繁体   中英

Why query does not fail with nonexistent column in subquery?

I misspelled in my query and faced with MySQL's strange behaviour.

create table aaa (id bigint auto_increment primary key, 
                  amount int not null, 
                  other_column varchar(20)) engine=InnoDB
create table bbb (aaa_id bigint not null, 
                  comment varchar(200), 
                  key(aaa_id)) engine=InnoDB; 
insert into aaa(other_column, amount) values ('hello, world', 12), 
                                             ('second string', 15), 
                                             ('one more', 100);
insert into bbb value (2, 'no 2s!');

The following query produces null result (I typed 'id' instead of 'aaa_id'):

select sum(amount) from aaa where id not in (select id from bbb);

"Maybe 'id' has special meaning for MySQL", I thought. But, the following query executes normally and returns 127 (as if subquery returns empty result):

select sum(amount) from aaa where id not in (select other_column from bbb);

The following queries produce expected result: first one fails with Unknown column 'id2' in 'field list' , and the second one returns 112 :

select sum(amount) from aaa where id not in (select id2 from bbb);
select sum(amount) from aaa where id not in (select aaa_id from bbb);

As it can be seen, MySQL somehow executes subquery if the column exists in the outer query. But what the meaning of those columns in the subquery?

Tested on 5.1.70 and 5.5.

This query:

select sum(amount)
from aaa
where id not in (select id from bbb);

Is interpreted as:

select sum(aaa.amount)
from aaa
where aaa.id not in (select aaa.id from bbb);

because bbb.id does not exist. When writing SQL, I suggest that you always use table aliases. The query that you thought you were writing:

select sum(aaa.amount)
from aaa
where aaa.id not in (select bbb.id from bbb);

would generate the error you expect.

If you created the bbb table like this:

create table bbb (aaa_id bigint not null, 
                  ^^^^^^

why would you use

select sum(amount) from aaa where id not in (select id from bbb);
                                                    ^^

then instead? The DB's not telepathic, it can't read your mind. If you tell it to use field x in a table, then it's going to need x to actually exist, and won't randomly pick some OTHER field.

The subquery COULD "reach out" and pick up field names from the outer/parent query, if tell the DB to do so, eg

SELECT id
FROM aaa
WHERE 
   id in (SELECT ... FROM bbb WHERE aaa.id = bbb.somefield)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM