zoukankan      html  css  js  c++  java
  • SQL数据查询之——嵌套查询

    一、概念描述

    在SQL语言中,一个 SELECT-FROM-WHERE 语句称为一个查询块。将一个查询块嵌套在另一个查询块的 WHERE 子句或 HAVING 短语的条件中的查询称为 嵌套查询。例如:

    SELECT Sname  /*外层查询或父查询*/
    FROM Student
    WHERE Sno IN
        (SELECT Sno  /*内层查询或子查询*/
         FROM SC
         WHERE Cno='2');

    SQL语言允许多层嵌套查询,即一个子查询中还可以嵌套其他子查询。

    注意:子查询的SELECT语句中不能使用 ORDER BY 子句,因为 ORDER BY 子句只能对最终查询结果排序。

    二、带有IN谓词的子查询

    在嵌套查询中,子查询的结果往往是一个集合,所以谓词 IN 是嵌套查询中最经常使用的谓词。

    查询与“刘晨”在同一个系学习的学生

    SELECT Sno,Sname,Sdept
    FROM Student
    WHERE Sdept IN
        (SELECT Sdept
         FROM Student
         WHERE Sname='刘晨');

    查询选修了课程名为“信息系统”的学生学号和姓名

    SELECT Sno,Sname /*最后在Student关系中取出Sno和Sname*/
    FROM Student
    WHERE Sno IN
        (SELECT Sno  /*然后在SC关系中找出选修了3号课程的学生学号*/
         FROM SC
         WHERE Cno IN
            (SELECT Cno  /*首先在Course关系中找出“信息系统”的课程号,结果为3号*/
             FROM Course
             WHERE Cname='信息系统'
            )
        );

    本查询同样可以用连接查询实现:

    SELECT Student.Sno,Sname
    FROM Student,SC,Course
    WHERE Student.Sno=SC.Sno AND
        SC.Cno=Course.Cno AND
        Course.Cname='信息系统';

    三、带有比较运算符的子查询

    带有比较运算符的子查询是指父查询与子查询之间用比较运算符进行连接。当用户能确切知道内层查询返回的是单个值时,可以用 >、<、=、>=、<=、!=、或<>等比较运算符。

    找出每个学生超过他自己选修课程平均成绩的课程号

    SELECT Sno,Cno
    FROM SC X
    WHERE Grade >=(SELECT AVG(Grade)
                   FROM SC y
                   WHERE y.Sno=x.Sno);

    四、带有ANY(SOME)或ALL谓词的子查询

    子查询返回单值时可以用比较运算符,但返回多值时要用ANY(有的系统用SOME)或ALL谓词修饰符。而使用ANY或ALL谓词时则必须同时使用比较运算符。其语义如下:

    >ANY

    大于子查询结果中的某个值

    >ALL

    大于子查询结果中的所有值

    <ANY

    小于子查询结果中的某个值

    <ALL

    小于子查询结果中的所有值

    >=ANY

    大于等于子查询结果中的某个值

    >=ALL

    大于等于子查询结果中的所有值

    <=ALL

    小于等于子查询结果中的所有值

    <=ANY

    大于等于子查询结果中的某个值

    =ANY

    等于子查询结果中的某个值

    =ALL

    等于子查询结果中的所有值(通常没有实际意义)

    !=(或<>ANY

    不等于子查询结果中的某个值

    !=(或<>ALL

    不等于子查询结果中的任何一个值

    查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名和年龄

    SELECT Sname,Sage
    FROM Student
    WHERE Sage<ANY (SELECT Sage
                    FROM Student
                    WHERE Sdept='CS')
    AND Sdept <> 'CS';

    查询非计算机科学系中比计算机科学系所有学生年龄都小的学生姓名和年龄

    SELECT Sname,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与聚集函数的对应关系表示如下

    五、带有 EXISTS 谓词的子查询

    带有EXISTS 谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”。

    查询所有选修了1号课程的学生姓名

    SELECT Sname
    FROM Student
    WHERE EXISTS
        (SELECT *
         FROM SC
         WHERE Sno=Student.Sno AND Cno='1');

    使用存在量词EXISTS后,若内层查询结果为空,则外层的WHERE子句返回真值,否则返回假值。

    查询没有选修1号课程的学生姓名

    SELECT Sname
    FROM Student
    WHERE NOT EXISTS
        (SELECT *
         FROM SC
         WHERE Sno=Student.Sno AND Cno='1');

    查询选修了全部课程的学生姓名

    由于没有全称量词,可将题目的意思转换成等价的用存在量词的形式:查询这样的学生,没有一门课程是他不选修的。

    SELECT Sname
    FROM Student
    WHERE NOT EXISTS
        (SELECT *
         FROM Course
         WHERE NOT EXISTS
            (SELECT *
             FROM SC
             WHERE Sno=Student.Sno
                AND Cno=Course.Cno));

    查询至少选修了学生201215122选修的全部课程的学生号码

    SELECT DISTINCT Sno
    FROM SC SCX
    WHERE NOT EXISTS
        (SELECT *
         FROM SC SCY
         WHERE SCY.Sno='201215122' AND
            NOT EXISTS
            (SELECT *
             FROM SC SCZ
             WHERE SCZ.Sno=SCX.Sno AND
             SCZ.Cno=SCY.Cno));

    六、总结

    此次学习和整理了有关SQL与嵌套查询相关的程序

    • 带有IN谓词
    • 带有比较运算符
    • 带有ANY或ALL
    • 带有EXISTS谓词

    尤其应格外重视 ANY、ALL与聚集函数的对应关系,还有带EXISTS时逻辑上的判断。

  • 相关阅读:
    监控里的主码流和子码流是什么意思
    监控硬盘容量计算
    一个能让你了解所有函数调用顺序的Android库
    电工选线
    oracle linux dtrace
    list all of the Oracle 12c hidden undocumented parameters
    Oracle Extended Tracing
    window 驱动开发
    win7 x64 dtrace
    How to Use Dtrace Tracing Ruby Executing
  • 原文地址:https://www.cnblogs.com/OctoptusLian/p/8183241.html
Copyright © 2011-2022 走看看