当前位置:操作系统 > Unix/Linux >>

嵌套查询实验

嵌套查询实验
 
1. 基础知识
    一个SELECT-FROM-WHERE语句称为一个查询块。
    将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询。
可以参看例1。   
>> 根据求解过程分子查询主要有
    (1)不相关子查询
    子查询的查询条件不依赖于父查询;
    由里向外,逐层处理。即每个子查询在上一级查询处理之前求解,子查询的结果用于建立其父查询的查找条件。
    (2)相关子查询
    子查询的查询条件依赖于父查询。
    首先取外层查询中表的第一个元组,根据它与内层查询相关的属性值处理内层查询,若WHERE子句返回值为真,则取此元组放入结果表;
    然后再取外层表的下一个元组;
    重复这一过程,直至外层表全部检查完为止。
>>根据嵌套的子句类型分嵌套查询主要类型
  1)带有IN谓词的子查询 
  2)带有比较运算符的子查询
  3)带有ANY(SOME)或ALL谓词的子查询
  4)带有EXISTS谓词的子查询
2. 实验案例
1)带有IN谓词的子查询。
例1.查询选修了2号课程的学生姓名。
[sql] view plaincopyprint?
--外查询:查询学号在子查询结果内的学生姓名。  
select sname  
from student  
where sno in (  
       --子查询:查询选修了2号课程的学生学号。  
      select sno  
         from sc  
         where cno = '2'  
)  
 
>>说明:
(1)以上查询中子查询跟外查询没关系,所以可以先做子查询,把结果作为外查询的where子句的一部分,再进行外查询的筛选条件得到结果,这种与外查询没关系的子查询称为为“不相关子查询”。
(2)子查询的限制“不能使用ORDER BY子句”。为什么?子查询是个中间结果,而排序只能对查询结果进行。
(3)层层嵌套方式反映了 SQL语言的结构化。
(4)有些嵌套查询可以用连接运算替代。把例1改成连接运算?
select sname
from student,sc
where student.sno = sc.sno and sc.cno = '2'
2)带有比较运算符的子查询
例2.查询每个学生学号和超过他选修课程平均成绩的课程号。
   SELECT Sno,Cno
    FROM SC  x
    WHERE Grade >=
                        (SELECT AVG(Grade)
                          FROM  SC y
                           WHEREy.Sno=x.Sno);
>>执行过程
<1> 从外层查询中取出SC的游标指向的(首次为第一行)元组x,将元组x的Sno值(200215121)传送给内层查询。
      SELECTAVG(Grade)
      FROM SC y
      WHERE y.Sno='200215121';
<2> 执行内层查询,得到值88(近似值),用该值代替内层查询,得到外层查询的查询条件,判断外层查询的当前元组是否满足条件:(满足,则该元组进入结果集,不满足时则不进入结果集)。
      SELECTSno, Cno
      FROM  SC x
      WHERE Grade >=88;
<3>外查询表游标下移,如果到了表的尾部,进入下一步结束。否则,返回第一步。
<4>结束。
 
>>说明:
当能确切知道内层查询返回单值时,可用比较运算符(>,<,=,>=,<=,!=或< >)。
与ANY或ALL谓词配合使用
 
3)带有ANY(SOME)或ALL谓词的子查询
例3.查询其他系中比计算机科学某一学生年龄小的学生姓名和年龄
   SELECT _______ , _______
   FROM   ___________
   WHERE Sage <  ________(SELECT  _________
                                        FROM    Student
                                         WHERE Sdept= 'CS ')
          ANDSdept<> ‘CS ' ;           /*父查询块中的条件 */
 
例4.查询其他系中比计算机科学系所有学生年龄都小的学生姓名及年龄。
方法一:用ALL谓词
   SELECTSname,Sage
   FROM Student
   WHERE Sage < ALL
                           (SELECT Sage
                            FROM Student
                            WHERE Sdept= 'CS ')
          AND Sdept<> ' CS ’;
 
 
方法二:用聚集函数
        SELECT Sname,Sage
        FROM Student
        WHERE Sage <
                               (SELECT MIN(Sage)
                                FROM Student
                                WHERE Sdept= 'CS ')
              AND Sdept<>' CS ’;
 
>>谓词语义
ANY:任意一个
ALL:所有值
 
4)带有EXISTS谓词的子查询
例5.查询所有选修了1号课程的学生姓名。
解题思路:
  本查询涉及Student和SC关系
  Student中依次取每个元组的Sno值,用此值去检查SC关系
  若SC中存在这样的元组,其Sno值等于此Student.Sno值,并且其Cno= '1',则取此Student.Sname送入结果关系
 
SELECT Sname
    FROM Student
    WHERE EXISTS
                   (SELECT *
                    FROM SC
                    WHERE Sno=Student.Sno AND Cno= ' 1')
 
>>说明:
1.EXISTS谓词——存在量词
 带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”。
 若内层查询结果非空,则外层的WHERE子句返回真值
 若内层查询结果为空,则外层的WHERE子句返回假值
 由EXISTS引出的子查询,其目标列表达式通常都用* ,因为带EXISTS的子查询只返回真值或假值,给出列名无实际意义
 
2.NOT EXISTS谓词
若内层查询结果非空,则外层的WHERE子句返回假值
若内层查询结果为空,则外层的WHERE子句返回真值
 
例6:查询没有选修1号课程的学生姓名。
     SELECT Sname
     FROM Student
     WHERE NOT EXISTS
                   (SELECT *
                  &nb
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,