Quantcast
Channel: SQLParty »子查询
Viewing all articles
Browse latest Browse all 2

使用in进行嵌套子查询,结果集不准确?

$
0
0

有以下两张表:

表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.


Viewing all articles
Browse latest Browse all 2

Trending Articles