这是哪门子的BUG,这已经算是相关子查询了,可以引用外部查询的列,也是引用了外部查询的一些列才叫相关子查询,在这边相当于对每行A表的记录查询B表的常量Aid,语法是合法的,逻辑上就没有意义了你可以换个没有Aid的表当外表试试,或者,单独执行没有Aid的表B的语句 select Aid from 表B 试试,看会不会报错
BUG还真是很稀罕的东东,普通人是很难遇到的.
唉,我只是把问题简化了而已。问题本质是:如果两个表有同一个字段,用这个字段来做子查询是无效的。我上面那个问题只是这个问题本质的衍生。--建表 create table tA(id varchar(10)) create table tB(id2 varchar(10))--测试数据 Insert into tA(id) select 1 union select 2 Insert into tB(id2) select 1--查询 select * from tA where id in (select id from tB)--删除表 drop table tA,tB 现在明白了吧?
我如果只回答,我还能说什么是对你不尊重,很明显,现在不明白的不是我,是你 select * from tA where id in (select id from tB) 这里面的这个id这个时候是tA的,因此,当tB的行数大于0时,这个查询永远为真,即所有的记录都会有,你换成EXISTS也是一样的情况和道理这个子查询,在tB存在id时,是标量子查询,而如果tB不存在id时,这时的id就是外部查询的,这个子查询就成了相关子查询了,子查询引用外部查询的列时,一般是放在WHERE子句里的,但是放到SELECT里面也是合法的这个不算BUG,这个在2005技术内幕里,作为开发团队的作者自己都提到了,这个逻辑上没有错,只是这个查询已经没有意义了不知道回答到你的点上了没有
select * from tA where id in (select id from tB) 不省略表名,就是 select tA.* from tA where tA.id in (select tA.id from tB) 你明白了吧?
select Aid from 表B
试试,看会不会报错
唉,我只是把问题简化了而已。问题本质是:如果两个表有同一个字段,用这个字段来做子查询是无效的。我上面那个问题只是这个问题本质的衍生。--建表
create table tA(id varchar(10))
create table tB(id2 varchar(10))--测试数据
Insert into tA(id)
select 1 union select 2
Insert into tB(id2)
select 1--查询
select * from tA where id in (select id from tB)--删除表
drop table tA,tB
现在明白了吧?
select * from tA where id in (select id from tB)
这里面的这个id这个时候是tA的,因此,当tB的行数大于0时,这个查询永远为真,即所有的记录都会有,你换成EXISTS也是一样的情况和道理这个子查询,在tB存在id时,是标量子查询,而如果tB不存在id时,这时的id就是外部查询的,这个子查询就成了相关子查询了,子查询引用外部查询的列时,一般是放在WHERE子句里的,但是放到SELECT里面也是合法的这个不算BUG,这个在2005技术内幕里,作为开发团队的作者自己都提到了,这个逻辑上没有错,只是这个查询已经没有意义了不知道回答到你的点上了没有
不省略表名,就是
select tA.* from tA where tA.id in (select tA.id from tB)
你明白了吧?