-
1 SQL不相关嵌套子查询
-
2 SQL相关嵌套子查询
SQL不相关嵌套子查询
大家都学习过高级编程语言,比如C语言;都知道类似if、for这样的流程控制语句是可以嵌套使用的。SQL嵌套子查询和if、for等语句的嵌套使用是一个道理,也就是说在一个查询语句中可以直接使用另一个查询语句的结果;或者说,一条查询语句可以嵌入到另一条查询语句内部使用。
那我们举个例子:
首先,上背景:

【例1】查询比张三年龄大的学生的姓名和年龄。
对于这道题,大家的思路应该都比较清楚:使用自连接查询即可完成,一张表去找张三的年龄,一张表对全体学生进行扫描,将其年龄和在上一张表中找到的张三的年龄进行比较;比如:
select s1.Sname,s1.Sage from Student s1,Student s2
where s2.Sname='张三' and s1.Sage>s2.Sage
其实大家也会留意到:我们的解题思路分为了两个步骤:
1、在一张表中去找到张三的年龄;
2、在另一张表种对全体学生进行扫描,测试其年龄是否大于在上一步中找到的张三的年龄。
其中第2步用到了第1步的结果。所以我们可以换个思路:
首先找到张三的年龄:select s2.Sage from Student s2 where s2.Sname='张三'
这条语句如果被执行,那么我们一定可以得到张三的年龄,而这个年龄一定是一个类似于17、18、19这样的具体数值,我们就直接假定是A(A=select s2.Sage from Student s2 where s2.Sname='张三')。
接下来,完成第2步:有了这个A以后,我们就可以再次对Student表进行全表搜索,来看看有哪些同学的年龄大于A:
select s1.Sname,s1.Sage from Student s1 where s1.Sage>A
就和数学里面的代数式一样,我们可以把A的表达式带入上述SQL语句:
select s1.Sname,s1.Sage from Student s1 where s1.Sage>(
select s2.Sage from Student s2 where s2.Sname='张三'
)
首先说明:这条语句的执行结果和例1中那条自连接查询的效果是完全一致的,即两条语句等价。大家可以很直观的看到:一条查询语句被嵌入到了另一条查询语句之中。那么这就是嵌套子查询。
我们来下两个定义:
外层查询:嵌套查询中的外部查询语句;
内层查询:嵌套查询中的内部查询语句,也被称作子查询。
其实上面这个将自连接写成嵌套查询的例子除了更符合我们的思维习惯,简化我们的编程以外,好像并没有更多地体现出嵌套查询的价值。接下来,我们再举一个例子:
【例2】查询学生平均年龄高于计科系的其它系。
这道题很难利用连接查询来实现。但是利用嵌套查询,则显得比较清晰,也比较容易。我们可以把思路捋一捋:
1、查询计科系的学生平均年龄
select avg(Sage) from Student group by Sdept
2、查询比第1步所得到的平均年龄要高的其它系
select Sdept from Student
group by Sdept having avg(Sage)>(
select avg(Sage) from Student group by Sdept
)
这就是最终的结果。整个SQL看起来非常清晰,理解起来也容易得多。
最后我们需要指出的是内层查询和外层查询的关系:在前面的两个例子中,内层查询都是可以独立完成的,换句话说,它并不需要外部给它传递任何参数;同时内层查询会先于外层查询执行,且只执行1遍。因为大家可以很容易地分析出来,内层查询不管执行几遍,结果都是唯一的,不会变化。
像这样的情况,我们就说内层查询不依赖于外层查询。我们把内层不依赖于外层的嵌套子查询称作不相关嵌套子查询。
再强调一遍:这里的不相关是指内层的执行和外层无关,但反过来讲是不成立的,即在嵌套子查询中外层是一定依赖于内层的,否则子查询的作用是什么呢?

