分步骤解析SQL的相关子查询

定义

在SQL语言中,一个SELECT-FROM-WHERE语句称为一个查询块。讲一个查询块嵌套在另一个查询块的WHERE子句或者HAVing短语的条件中的查询称为嵌套查询。其中上层查询块称为外层查询或者父查询,下层查询称为内查询或者子查询。

根据子查询是否依赖于父查询,可以分为不相关子查询和相关子查询。其中子查询的查询条件不依赖于父查询,称为不相关子查询,如果子查询的查询条件依赖于父查询,则这类子查询称之为相关子查询。

案例

数据准备

学号 课程号 成绩
201215121 1 92
201215121 2 85
201215121 3 88
201215122 2 90
201215122 3 80
Create table If Not Exists SC (Sno char(9), Cno char(4),Grade SMALLINT);
Truncate table SC;
insert into SC values ('201215121','1', 92);
insert into SC values ('201215121','2', 85);
insert into SC values ('201215121','3', 88);
insert into SC values ('201215122','2',90);
insert into SC values ('201215122','3',80);

分析

  • 找出每个学生超过他自己选修课程平均分的课程号
SELECT Sno,Cno 
FROM SC x
WHERE Grade >= ( SELECT avg( Grade )
FROM SC y
WHERE y.Sno = x.Sno )

x是SC的别名,又称为元祖变量,可以用来表示SC的一个元祖。内层查询时求一个学生所有选修课程的平均成绩的,至于是哪一个学生的平均成绩要看参数x.Sno的值,而该值是与父查询相关的,因此这类查询称之为相关子查询。

这个语句的一种可能执行过程采用以下三个步骤。

1.从外层查询中取出SC的一个元祖x,将元祖x的Sno值(201215121)传送给内层查询。

SELECT AVG(Grade)
FROM SC y
WHERE y.Sno='201215121';

2.执行内层查询,得到值88(近似值),用该值代替内层查询,得到外层查询:

SELECT Sno,Cno
FROM SC x
WHERE Grade > 88;

3.执行这个查询,得到 (201215121,1)

然后外层查询取出下一个元祖重复上述1至2步骤的处理,直到外层的SC元祖全部处理完毕。


  • reference

    [1]王珊, 萨师煊. 数据库系统概论(第5版)