为什么查询不会因子查询中不存在的列而失败?

时间:2015-04-13 18:09:02

标签: mysql

我在查询中拼错了,面对MySQL的奇怪行为。

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!');

以下查询产生null结果(我输入'id'而不是'aaa_id'):

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

“也许'id'对MySQL有特殊意义”,我想。但是,以下查询正常执行并返回127(就好像子查询返回空结果):

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

以下查询产生预期结果:第一个查询失败,Unknown column 'id2' in 'field list'失败,第二个回复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);

可以看出,如果列存在于外部查询中,MySQL会以某种方式执行子查询。但子查询中这些列的含义是什么?

在5.1.70和5.5上测试。

2 个答案:

答案 0 :(得分:3)

此查询:

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

被解释为:

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

因为bbb.id不存在。编写SQL时,我建议您始终使用表别名。您认为正在编写的查询:

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

会产生您期望的错误。

答案 1 :(得分:0)

如果你创建了这样的bbb表:

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

你为什么要用

select sum(amount) from aaa where id not in (select id from bbb);
                                                    ^^
那么呢? DB不是心灵感应,它无法读懂你的想法。如果您告诉它在表格中使用字段x,那么它实际上需要x,并且不会随机选择其他字段。

子查询可以“伸出”并从外部/父查询中选取字段名称,如果告诉DB这样做,例如

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