SQL的执行过程

MercuryGG 2011-03-23 10:36:11
select sid
from S
where not exists(select *
from C
where not exists(select *
from SC
where cno=C.cno))
比如S表中SNO字段数据为1,2,3,对应的字段sid为甲乙丙,C表中字段数据为11,22,33
SNO和CNO为SC表的外键,在SC表中对应的字段数据分别是1,11 2,11 2,22 3,11 3,22 3,33
上面的字段是如何执行的,然后得到的S表中的SNO是,如何一步步执行....
比如
select Sid
from S
where exists(select *
from SC
where sno=S.sno AND cno='11')
他的执行过程应该是,先从S表中取出一个元组,用其中的sno去检查SC表,若存在这样的满足WHERE条件的元组,则去S表此元组的sid放到结果表.
因为第一个SQL语句有多层NOT EXIST,他的执行过程应该是?求高人指点。。。
...全文
159 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
MercuryGG 2011-03-23
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 ssp2009 的回复:]

引用 4 楼 mercurygg 的回复:
SQL code
select sid
from S
where not exists(select *
from C
where not exists(select *
from SC
where cno=C.cno AND sno=S.sno))

对不起楼上,由于写的比较快没来得及仔细检查,上面的SQL语句少写了一个WHERE……
[/Quote]
额,感谢SSP2009的回复
这样是方便理解了,可是用此SQL语句得到的结果和原来的不一样...
MercuryGG 2011-03-23
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 fredrickhu 的回复:]

楼主可以把这个SQL语句想象成双重否定


NOT EXISTS就是不存在 得到的值是个BOOL值


所以是先执行NOT EXISTS子查询的内容 再执行外面的语句
[/Quote]
非常感谢LS回复,其实我也觉得应该先执行里面的子查询的内容,可是给这个两重逻辑绕晕了,所以我才在下面给出一个小的数据,用实际数据来加深对执行过程的理解.
比如没有楼顶贴中嵌套查询的那个,我知道是先取一个元组,SNO:1,SID:甲 ,把SNO传到SC里面对比,找到SC中有1,11的元组,所以甲返回结果集。然后取第二个元组,SNO:2,SID:乙……最后得出结果集甲乙丙。
可是遇到这两个的逻辑,我就给绕到了…
快溜 2011-03-23
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 mercurygg 的回复:]
SQL code
select sid
from S
where not exists(select *
from C
where not exists(select *
from SC
where cno=C.cno AND sno=S.sno))

对不起楼上,由于写的比较快没来得及仔细检查,上面的SQL语句少写了一个WHERE条件应该是这样的...我主要想知……
[/Quote]
三张表嵌套,sc表作为c表的内表,sc和c查出来的集合作为s表的内表
改成这样方便你理解
select sid from s
where not exists( select 1 from (select sc.sno from c,sc where c.cno=sc.cno) a
where sno=s.sno)
--小F-- 2011-03-23
  • 打赏
  • 举报
回复
楼主可以把这个SQL语句想象成双重否定


NOT EXISTS就是不存在 得到的值是个BOOL值


所以是先执行NOT EXISTS子查询的内容 再执行外面的语句
MercuryGG 2011-03-23
  • 打赏
  • 举报
回复
select sid
from S
where not exists(select *
from C
where not exists(select *
from SC
where cno=C.cno AND sno=S.sno))

对不起楼上,由于写的比较快没来得及仔细检查,上面的SQL语句少写了一个WHERE条件应该是这样的...我主要想知道的SQL的执行过程中是如何一步一步处理的.数据库中的数据拿楼顶的数据.
快溜 2011-03-23
  • 打赏
  • 举报
回复
select sid from S
where not exists(select * from C
where not exists(select * from SC
where cno=C.cno))
--你这种写法查出来只有两种结果,要么一个都查不出来,要么select出来全部。
--如果sc表里有cno跟c表cno一样的,返回true,那么select s表的全部,否则相反
MercuryGG 2011-03-23
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 shmilywcd 的回复:]

请查看数据库 执行计划
[/Quote]
首先感谢LS回复
小弟初学SQL,请问如何查看数据库的执行计划...
天-笑 2011-03-23
  • 打赏
  • 举报
回复
请查看数据库 执行计划

MercuryGG 2011-03-23
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 feilniu 的回复:]

一层的相关子查询搞清楚了,多层的无非是嵌套而已。

还是要从SQL的语义、即查询的逻辑处理过程入手来理解。否则数据量大了,你总不可能一条一条分析。
[/Quote]
非常感谢,前面饶的有点晕...后面您说到和5楼一样的双重否定的时候大概就明白了,非常感谢您的耐心..
feilniu 2011-03-23
  • 打赏
  • 举报
回复
一层的相关子查询搞清楚了,多层的无非是嵌套而已。

还是要从SQL的语义、即查询的逻辑处理过程入手来理解。否则数据量大了,你总不可能一条一条分析。
feilniu 2011-03-23
  • 打赏
  • 举报
回复

--查询1
SELECT S.sid
FROM S
WHERE NOT EXISTS(
SELECT *
FROM C
WHERE NOT EXISTS(
SELECT *
FROM SC
WHERE SC.cno = C.cno
AND SC.sno = S.sno
)
)
对于S表的(甲 1),判断如下查询2-1是否有结果,若没有结果则返回。
--查询2-1
SELECT *
FROM C
WHERE NOT EXISTS(
SELECT *
FROM SC
WHERE SC.cno = C.cno
AND SC.sno = 1
)
对于C表的11,SC表存在(1,11),不返回;
对于C表的22,SC表不存在(1,22),返回;BREAK
因为22返回,查询2-1有结果,所以查询1的(甲 1)不返回。
对于S表的(丙 3), 判断如下查询2-3是否有结果,若没有结果则返回。
--查询2-3
SELECT *
FROM C
WHERE NOT EXISTS(
SELECT *
FROM SC
WHERE SC.cno = C.cno
AND SC.sno = 3
)
对于C表的11,SC表存在(3,11),不返回;
对于C表的22,SC表存在(3,22),不返回;
对于C表的33,SC表存在(3,33),不返回;
因为查询2-3无结果,所以查询1的(丙 3)返回。

MercuryGG 2011-03-23
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 bala7229291 的回复:]

不知道我这样分析对不对,
第一步:查询分析器读到“select sid from S where not exists...”知道要完成这条语句得先得到not exists后面查询的值,这个值是一个真或者假.

第二步:查询分析器读到“select * from C where not exists”知道要完成这条语句得先得到not exists后面查询的值,这个值是一个真或者假

第……
[/Quote]
感谢,半明白状态,请问能用9L的实际数据来说明一下情况么?再次感谢...
MercuryGG 2011-03-23
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 feilniu 的回复:]

SQL code

SELECT S.sid
FROM S
WHERE NOT EXISTS(
SELECT *
FROM C
WHERE NOT EXISTS(
SELECT *
FROM SC
WHERE SC.cno = C.cno
AND SC.sno = S.sno
)
)


……
[/Quote]
非常感谢,好像有点理解了,就是5楼说的双重否定的意思...
但还是有的地方不是很理解,要表达好象也表达不出来.能不能麻烦细说以下具体的数据传入的过程,详细数据我在9L贴出来.一到具体的数据,我发现又绕不过来了...
bala7229291 2011-03-23
  • 打赏
  • 举报
回复
不知道我这样分析对不对,
第一步:查询分析器读到“select sid from S where not exists...”知道要完成这条语句得先得到not exists后面查询的值,这个值是一个真或者假.

第二步:查询分析器读到“select * from C where not exists”知道要完成这条语句得先得到not exists后面查询的值,这个值是一个真或者假

第三步:查询分析器读到“select * from SC where cno=C.cno AND sno=S.sno”,这时就开始连接SC表和C表(是否满足SC.cno = C.cno),如果不满足向则向第二步返回不存在(真),如果满足就继续连接SC表和S表(SC.sno=S.sno),如果不满足向则向第二步返回不存在(真),如果满足则返回第二步存在(假)

第四步:如果第二步得到真,则执行“select * from C”返回所有记录,向第一步返回存在(假),如果假则不返回记录,向第一步返回不存在(真)

第五步:第一步如果得到真,则执行 “select sid from S”,如果得到假则不执行,得到0条记录
feilniu 2011-03-23
  • 打赏
  • 举报
回复

SELECT S.sid
FROM S
WHERE NOT EXISTS(
SELECT *
FROM C
WHERE NOT EXISTS(
SELECT *
FROM SC
WHERE SC.cno = C.cno
AND SC.sno = S.sno
)
)

查询S,使得不存在C,没有SC的组合。
即:
查询S,对于所有C都有SC的组合。
代码可以写成:

SELECT S.sid
FROM S
WHERE S.sno IN (
SELECT SC.sno
FROM SC
INNER JOIN C
ON SC.cno = C.cno
GROUP BY SC.sno
HAVING COUNT(*) = (SELECT COUNT(*) FROM C)
)

MercuryGG 2011-03-23
  • 打赏
  • 举报
回复
假如S表
sid sno
甲 1
乙 2
丙 3
C表
cno
11
22
33
SC表
sno cno
1 11
2 11
2 22
3 11
3 22
3 33
执行过程是怎么样的,再顶一下

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧