有以下两张表:
表1、items
+-------------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | short_description | varchar(255) | YES | | NULL | | | description | text | YES | | NULL | | | example | text | YES | | NULL | | | explanation | text | YES | | NULL | | | additional | text | YES | | NULL | | +-------------------+--------------+------+-----+---------+-------+
表2、items_links
+--------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+---------+------+-----+---------+-------+ | iid | int(11) | NO | PRI | NULL | | | linkid | int(11) | YES | | NULL | | +--------+---------+------+-----+---------+-------+
执行如下语句:
select count(*) from items where id in (select id from items_links)
返回10。再执行如下语句:
select count(*) from items_links
返回6。
这个就很奇怪了,第一次执行应该最多就6条才对?什么原因呢?
这题既是考察SQL语法,也是考察仔细程度和书写习惯。查看两表的字段定义,我们发现items_links没有id字段,而是iid。而第一句SQL中的子查询(select id from items_links)中的id来自哪里呢?将该子查询取出来单独执行。
select id from items_links; ERROR 1054 (42S22): Unknown column 'id' in 'field list'
现在可以很清楚看到,该查询是个关联子查询,即子查询包括了外查询的字段,id为外表items的id字段。where取外表每一条记录进行谓词判断,假如判断id=6,则谓词变成了
6 in (select 6 from items_links)
只要items_links表有记录,其必然返回true。本题的修改很简单,将子查询的中id改为iid即可。
本题中可以看出,子查询中,如果指定的列不存在,它会到外部表中寻找,这一定程度上容易造成混淆!根本解决方案是:任何对字段的应用都加上表或表别名的限制。
所以更合理的本题修改方案应该是:
select count(*) from items i where i.id in (select il.iid from items_links il)
The post 使用in进行嵌套子查询,结果集不准确? appeared first on SQLParty.