利用SQL语言表达复杂查询

这篇博客主要介绍一些复杂的sql查询,DDL和简单的sql部分这里不做介绍

先贴表结构:




出现在where子句中的select语句被称为子查询,子查询返回了一个集合,可以通过和这个集合的比较来确定另一个集合

三种类型的子查询:

  • (NOT)IN子查询
  •  Some 与 All 子查询
  • (NOT)EXISTS 子查询

SQL语言表达复杂查询--(NOT)IN 子查询

示例1、列出张三、王三同学的所有信息

select * from student
where sname in ("张三", "王三")

示例2、列出选修了001号课程的学生的学号和姓名

select S#, Sname from student
where S# in (select * from sc where C#='001')

示例3、求既学过001号课程又学过002号课程的同学

select S# from SC
where C#='001' AND 
S# in (select S# from SC where C#='002')

示例4、列出没学过李明老师所授课程的所有同学的姓名

select Sname from Student
where S# not in (select S# from SC, Course C, Teacher T
where T.Tname='李明' and SC.C#=C.C# and C.T#=T.T#)

非相关子查询:内层查询独立进行,没有涉及外层查询相关信息的子查询

以上都是非相关子查询

相关子查询需要外层查询的某些参量作为限定条件才能进行的查询

  • 外层向内层传递的参量需要外层的表名或表别名来限定

示例:求学过001号课程的同学的姓名

select Sname from Student stu
where S# in(select S# from SC
where S#=stu.S# and C#='001')

SQL语言表达复杂查询-- Some 与All 子查询

示例1、找出工资最低的教师姓名

select Tname from Teacher
where salary <= all(select salary from Teacher)
示例2、找出001号课成绩不是最高的所有学生学号
select S# from SC
where C#='001' and score < some (select score from SC where C#='001')
示例3、找出所有课程都不及格的学生的姓名(相关子查询)
select Sname from Student S
where 60 > all(select score from SC
where S.S#=SC.S#)
示例4、找出98030101号同学成绩最低的课程号
select C# from SC
where S#='98030101' and score <= all (select score from SC
where S#='98030101'
)
示例5、找出张三同学成绩最低的课程号(相关子查询)
select C# from SC, Student S
where S.S#=SC.S# and Sname='张三' and score <= all(select score from SC
where S#=S.S#)

SQL语言表达复杂查询--(NOT)EXISTS 子查询

示例1、检索选修了赵三老师主讲课程的所有同学的姓名
select DISTINCT Sname from Student S
where exists(select * from SC, Course C, Teacher T
where S.S#=SC.S# and SC.C#=C.C# and C.T#=T.T# and T.Tname='赵三')

不加not形式的exists可以不用,例如上面的例子还可以写成如下形式:

select DISTINCT Sname From Student, SC, Course, Teacher
Where SC.C# = Course.C# and SC.S# = Student.S#
and Course.T# = Teacher.T#  and Tname = '赵三';

然而not exists 却可以实现许多新功能

示例2、检索学过001号教师的所有课程的所有学生姓名

select Sname from Student S
where not exists     -- 不存在
(select * from Course C    -- 有一门001老师主讲的课
where C.T#='001' and not exists   -- 他没学过
(select * from SC
where SC.S#=S.S# and SC.C#=C.C#))

上述语句的意思是:不存在又一门001老师主讲的课他没学过

示例3、列出没学过李明老师任何一门课的所有学生姓名

select Sname from Student S
where not exists(select * from Course C, SC, Teacher T
where Tname='李明' and T.T#=C.T# and C.C#=SC.C# and SC.S#=S.S#
)

示例4、列出至少学过98030101号同学学过所有课程的同学的学号

select S# from SC SC1
where not exists(select * from SC SC SC2
where S#='98030101' and not exists(select * from SC
where SC.C#=SC2.C# and SC.S#=SC1.S#))


SQL语言表达复杂查询--分组查询与分组过滤

  • 分组查询

示例1、求每一个学生的平均成绩

select S#, AVG(Score) from SC
group by S#

示例2、求每一门课的平均成绩

select C#, AVG(Score) from SC
group by C#

  • 分组过滤

示例1、求不及格课程超过两门的学生学号

select S# from SC
where Score < 60
group by S# having count(*) > 2

示例2、求有十人以上不及格的课程号

select C#, count(*) from SC
where Score < 60
group by C# having count(*) > 10

示例3、求有两门以上不及格同学的学号及其平均成绩

select S#, AVG(Score) from SC
where S# in(select S# from SC
where Score < 60
group by S# having count(*) > 2)
group by S#


猜你喜欢

转载自blog.csdn.net/GreenHandCGL/article/details/79734555
今日推荐