SQL Server 之 子查询与嵌套查询

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL Server 之 子查询与嵌套查询相关的知识,希望对你有一定的参考价值。

参考技术A 当由where子句指定的搜索条件指向另一张表时,就需要使用子查询或嵌套查询。

1 子查询

子查询是一个嵌套在select、insert、update或delete语句或其他子查询中的查询。任何允许使用表达式的地方都可以使用子查询。

1.1语法规则:

- 子查询的select查询使用圆括号括起来

- 不能包括compute或for browse子句

- 如果同时指定top子句,则可能只包括order by子句

- 子查询最多嵌套32层,个别查询可能会不支持32层嵌套

- 任何可以使用表达式的地方都可以使用子查询,主要它返回的是单个值

- 如果某个表只出现在子查询中而不出现在外部查询中,那么该表中的列就无法包含在输出中

1.2 语法格式:

- where 查询表达式 [not] in(子查询)

- where 查询表达式 比较运算符 [any|all] (子查询)

- where [not] exists (子查询)

2 嵌套查询

嵌套查询是指将一个查询块嵌套在另一个查询块的where子句或having短语的条件中的查询。

嵌套查询中上层的查询块称为外侧查询或父查询,下层查询块称为内层查询或子查询。SQL语言允许多层嵌套,但是在子查询中不允许出现order by子句,order by子句只能用在最外层的查询中。

嵌套查询的处理方法是:先处理最内侧的子查询,然后一层一层地向上处理,直到最外层的查询块。

2.1 简单的嵌套查询

子查询的运算符含有=、<>、<、>、<=、>=

三个查询:

第一个:查询年纪>25的老师所教的学生

第二个:查询年纪>25的老师

第三个:验证查询到的学生信息

对比:当子查询中的分那会的结果不是一个时,父查询无法正常工作

2.2 带IN的嵌套查询

当子查询返回一系列值时,适合带IN的嵌套查询。

2.3 NOT IN

2.4 SOME

2.5 ANY

2.6 ALL

2.7 EXIST

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时逻辑上的判断。

 

以上是关于SQL Server 之 子查询与嵌套查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL数据查询之——嵌套查询

如果嵌套查询在 SQL Server 中是不是有结果,如何返回是或否?

数据库开发基础-SQl Server 主键外键子查询(嵌套查询)

SQL Server 查询以根据用户提供的 id 获取嵌套的子记录

在sql中对不相关嵌套查询的处理原则

嵌套查询与连接查询的区别是啥