Sql Server 06

 

目录

 

嵌套查询

1.带有IN谓词的子查询

         相关子查询和不相关子查询

         2.带有比较运算符的子查询

         3.带有ANY(SOME)或ALL谓词的子查询

         4.带有EXISTS谓词的子查询


嵌套查询

1.带有IN谓词的子查询

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

第一种方法:分布进行查询

  1.  确定“刘晨“所在系名
    select Sdept
    from student
    where Sname = '刘晨';
    

     

                 Sql Server 06_第1张图片

2.查找所有在CS系学习的学生

select Sno,Sname,Sdept
from Student
where Sdept='CS';

Sql Server 06_第2张图片

 

第二种方法:将第一步查询嵌入到第二步查询的条件中

select Sno,Sname,Sdept
from Student
where Sdept in
(select Sdept
from Student
where Sname = '刘晨');

 第三种方法:用自身连接完成

select S1.Sno,S1.Sname,S1.Sdept
from Student S1,Student S2
where S1.Sdept=S2.Sdept and S2.Sname = '刘晨';

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

select Sno,Sname
from Student		-- 最后在Student中取出Sno 和 Sname
where Sno in
 (select Sno
	from SC  --然后在SC关系中找到 与找到的课程号相符的
	where Cno in
	(select Cno
	from Course
	where Cname = '信息系统' --先在Course中找到”信息系统的课程号
	)
	);

Sql Server 06_第3张图片

 

用连接查询实现

select Student.Sno,Sname
from Student,Course,SC
where Student.Sno = SC.Sno and
SC.Cno =Course.Cno and Course.Cname= '信息系统';

注:select Sno。。。会提示列名’Sno'不明确 是因为 多个表中都有Sno 需要指明你要查询的表

 

相关子查询和不相关子查询

 

不相关子查询:子查询的查询条件不依赖于父查询

n 由里向外 逐层处理 。即每个子查询在上一级查询处理之前求解,子查询的结果用于建立其父查询的查找条件。

   SELECT Sno, Sname, Sdept

      FROM Student

     WHERE Sdept  IN

                  (SELECT Sdept

                   FROM Student

                   WHERE Sname= ' 刘晨 ');

 

相关子查询:子查询的查询条件依赖于父查询

由外向里

取外层查询中表的第一个元组,根据它与内层查询相关的属性值处理内层查询,若WHERE子句返回值为真,则取此元组放入结果表

②再取外层表的下一个元组

③重复这一过程,直至外层表全部检查完为止

 

[3.57 ]找出每个学生超过他选修课程平均成绩的课程号。

select Sno,Cno
from SC x
where Grade >=(select avg(Grade)
from SC y
where y.Sno = x.Sno);

Q:哪里体现了选修?

 

2.带有比较运算符的子查询

当能确切知道内层查询返回单值时,可用比较运算符( > < = >= <= != < > )。
 

[3.55]中,由于一个学生只可能在一个系学习,则可以= 代替IN

select Sno,Sname,Sdept
from Student
where Sdept = (select Sdept
from Student
where Sname = '刘晨');

 

3.带有ANY(SOME)或ALL谓词的子查询

带有AN使用ANYALL谓词时必须同时使用比较运算

语义为:

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

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

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

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

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

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

 

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

select Sname,Sage
from Student
where Sage'CS';

Sql Server 06_第4张图片

 

select Sname,Sage
from Student
where Sage <
    (select max(Sage)--任意一个小 比最大的小就可以了
     from Student 
	 where Sdept = 'CS') 
and Sdept <>'CS';

 

[3.59]  查询非计算机科学系中比计算机科学系所有学生年龄都小的学生姓名及年龄。

-​​​​​用all

select Sname,Sage
from Student 
where Sage'CS';

       -用聚集函数

select Sname,Sage
from Student
where Sage< --比所有都小 需要比最小值小
(select min(Sage)
from Student 
where Sdept = 'CS')
and Sdept <> 'CS';

  4.带有EXISTS谓词的子查询

 EXISTS谓词
 
带有 EXISTS 谓词的子查询不返回任何数据,只产生逻辑真值“ true” 或逻辑假值“ false”
l. 若内层查询结果 非空 ,则外层的 WHERE 子句 返回真值
lI. 若内层查询结果为 ,则外层的 WHERE 子句 返回假值

                  由EXISTS引出的子查询,其目标列表达式通常都用 * ,因为带EXISTS的子查询只返回真值或假值,给出列名无实际意义。

NOT EXISTS谓词
 
若内层查询结果非空,则外层的 WHERE 子句返回假值
若内层查询结果为空,则外层的 WHERE 子句返回真值
 
 

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

select Sname 
from Student
where exists --取满足条件的Student.Sname
(select *
 from SC 
 where Sno=Student.Sno and Cno = '1'); --在Student中依次取每个元组的Sno 对应SC表的并且 其Cno =1

[3.61]  查询没有选修1号课程的学生姓名。

select Sname
from Student
where not exists --当存在是返回的false 也就是不满足时是true
(select * 
 from SC
 where Sno = Student.Sno and Cno = '1');

 

一些带EXISTSNOT EXISTS谓词的子查询不能被其他形式的子查询等价替换

所有IN谓词、比较运算符、ANYALL谓词的子查询

用带EXISTS谓词的子查询 等价替换

 

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

select Sno,Sname,Sdept
from Student S1
where exists --存在和刘晨Sdept一样的学生
(select *
 from Student S2
 where S2.Sdept = S1.Sdept and
  S2.Sname = '刘晨');

 

EXISTS / NOT EXISTS实现全称量词

[3.62] 查询选修全部课程的学生姓名。(转义后的表达:没有一门课程是他不选修的)

select Sname
from Student 
where not exists -- 内层返回了false 本层返回true 即得到了没有一门没选修的同学
(select *
 from Course
 where not exists -- 选修了就返回false 没选修返回true 最后说明这位同学有没选修的
 (select *
   from SC
   where Sno = Student.Sno
   and Cno = Course.Cno
   )
);

 

EXISTS / NOT EXISTS 实现逻辑蕴涵
 

 [3.63]查询至少选修学生201215122选修的全部课程的学生号码。

select distinct Sno
from SC SCX
where not exists 
    (select *
	  from SC SCY
	  where SCY.Sno = '201215122' and
	   not exists --若有122选择了但当前的同学没选择 返回true
	   (select *
	   from SC SCZ
	   where SCZ.Sno = SCX.Sno and
	   SCZ.Cno = SCY.Cno)
	 );

 

你可能感兴趣的:(DB实验,sql)