主题:sql嵌套语句怎样执行?
endlessrain
[专家分:10] 发布于 2007-06-28 12:56:00
select 名称 as 供应商名称 from 供应商表
where not exists
(select * from 零件表
where not exists
(select * from 供应表
where 供应商编号=供应商表.供应商编号 and 零件编号=零件表.零件编号))
是不是先执行
select * from 零件表
where not exists
(select * from 供应表
where 零件编号=零件表.零件编号)
得到的结果为空
后执行
select 名称 as 供应商名称 from 供应商表
where not exists ......
可整个语句却能得到准确的结果
这语句到底是怎么执行的啊
回复列表 (共7个回复)
沙发
ilovemountainking [专家分:3730] 发布于 2007-06-28 14:15:00
for(int i=0;i<n1;i++)
for(int j=0;j<n2;j++)
for(int k=0;k<n3;k++){
int l=i+j+k;
}
}
}
类似上面的表达式的执行过程,其中i,j,k是各自的表里的记录,你自己琢磨一下吧。。。。
板凳
endlessrain [专家分:10] 发布于 2007-06-28 16:29:00
大哥
你的意思也就是先执行里面的
可是就是我上面说的啊
第一个执行的结果为空啊
3 楼
菜鸭 [专家分:5120] 发布于 2007-06-29 07:45:00
是不是先执行
select * from 零件表
where not exists
(select * from 供应表
where 零件编号=零件表.零件编号)
得到的结果为空
后执行
select 名称 as 供应商名称 from 供应商表
where not exists ......
=======================
因为用的是not exists
如果结果为空
就执行
select 名称 as 供应商名称 from 供应商表
如果用的是exists
就相反
如果结果不为空
就执行外面的语句
4 楼
endlessrain [专家分:10] 发布于 2007-06-29 09:13:00
着我知道,关键是结果怎么会是,
"提供了所有零件的供应商名称"
5 楼
endlessrain [专家分:10] 发布于 2007-06-29 09:14:00
着我知道,关键是结果怎么会是,
"提供了所有零件的供应商名称"
我想不通啊
6 楼
joe2002 [专家分:80] 发布于 2007-07-11 17:43:00
这是个典型的相关子查询。所谓相关,是指子查询引用了上层表的数据。
为了说明其执行过程,简单起见,先看一个只有二层的,以上面的表为例子,下面这个SQL语句查询的是,还没有任何供应商供应的零件清单。
select *
from 零件表
where not exists
(select *
from 供应表
where 零件编号=零件表.零件编号)
执行过程逻辑上如下
1. open 零件表, 设置一个扫描游标 C1
2. if EOF(C1) then goto 6 //如果取完了则结束
else fetch C1 into x //取得一行零件数据,设为 x
3. open 供应表, 设置一个扫描游标 C2
4. if EOF(C2) then //如果取完,则表示没有找到相等的记录,
insert x into R; //把x插入结果集合R
close C2;
goto 2; //继续扫描零件表
else fetch C2 into y //取得一行供应商数据,设为 y
5. if x.零件编号 == y.零件编号 then
close C2; //找到相等记录,继续处理零件表
goto 2;
else
goto 4 //继续扫描供应表
6. close C1
7. 返回 R
对于3层及更多层的相关子查询,也是类似的处理方式,只不过相应需要同时处理的表更多。
希望这么表达能对楼主有所帮助!
7 楼
joe2002 [专家分:80] 发布于 2007-07-12 10:02:00
对于查询的子查询,先计算内层的子查询得到一个结果集合,再计算外层,如
求"供应商编号"为 10 的供应商所供应的零件清单:
SELECT *
FROM 零件表
WHEERe 零件编号 in
( SELECT 零件编号
FROM 供应表
WHERE 供应商编号 = 10)
但是对于EXISTS/NOT EXISTS谓词的相关子查询,不能先算里面的,再算外面的;而是必须一起算,而且是以外层为主导驱动。
下面把楼主的原始语句执行逻辑写一遍;实际的数据库管理系统采用更优化的等价算法:
R = NIL; // 初始设置结果集合为空集
open 供应商表 as C1; //准备扫描,设置游标C1
while not EOF(C1) do //依次扫描C1
begin
fetch C1 into x; //取一行供应商表记录
R1 = NIL; //初始化临时结果集,用于存放零件表记录
open 零件表 as C2; //准备扫描,设置游标C2
while not EOF(c2) do //依次扫描C2
begin
fetch C2 into y; //取一行零件表记录
R2 = NIL; //初始化临时结果集,用于存放供应表记录
open 供应表 as C3; //准备扫描,设置游标C3
while not EOF(c3) do
begin
fetch C3 into z;
if (z.供应商编号 == x.供应商编号
and z.零件编号 = y.零件编号) then
begin //找到符合条件的记录
insert z into R2; //插入临时表
break; //对于(NOT) EXISTS, 找到一条即可
end;
end;
close C3;
if R2 is NIL then //第3层没找到过符合条件的?(NOT EXISTS)
begin
insert into y into R1; //插入临时表
break; //找到一条即可
end;
end;
close C2;
if R1 is NIL then //第2层没找到过符合条件的?(NOT EXISTS)
begin
insert into x into R1; //插入最终结果集合
end;
end;
close C1;
return R; //得到结果
我来回复