【例3.49】
查询学生的选修课程情况
首先引入知识点:连接查询其实就是对于多个表进行笛卡尔积。
select Student.*,Sc.*
from TEST.Student,TEST.SC
where Student.Sno=Sc.Sno
上面的例子是等值查询,where的条件是‘=’ ,也可以是非等值查询将条件改为‘!=’即可。
【例3.50】
用自然连接完成上述的【3.49】
首先引入 自然连接:
自然连接:类似于关系代数的自然连接,不在赘述
select Student.Sno ,Sname ,Ssex,Sage,Cno,Grade
from TEST.Student ,TEst.SC
where Student.Sno=Sc.Sno
值得说明的是:需要在select后列出所有的符合条件的属性列。在上面的例子中就是Student.Sno ,Sname ,Ssex,Sage,Cno,Grade 属性
【例3.51】
选择学生选择课程为2,分数大于85
select Student.Sno,Sname
from TEST.Student,TEST.SC
where Student.Sno=SC.Sno and Cno='2' and Grade >85
这个例子使用and作为条件的叠加
【例3.52】
查询每一个课程的先修课
select f.Cno, f.Cname,s.Cpno
from TEST.Course f,TEST.Course s
where f.Cpno=s.Cno
上面的例子中使用的是自身连接,可以认为是将一个表看作是两个不同的表进行连接
【3.53】
修改【3.49】查询每一个学生选修以及没有选课的学生情况:
首先在此引入知识点:外连接
分为左外,右外连接 左外将左面的元组都显示出来,右面没有匹配的为空。右外同理
select Student.Sno,Sname,Ssex,Cno,Grade
from TEST.Student left outer join TEST.SC on(Student.Sno=Sc.Sno)
可以看到对于2021 这个同学Cno,Grade 属性为NULL,左外连接
再看右外连接
select Student.Sno,Sname,Ssex,Cno,Grade
from TEST.Student right outer join TEST.SC on(Student.Sno=Sc.Sno)
这个例子没有出现左面NULL的情况,使用这个例子说明右外连接其实不太合适,因为 SC的Sno来自于Student的Sno,一定会与Student的学号对应。
【3.54】查询每一个选课学生的成绩,学号,姓名。选修课程号,成绩
select Student.Sno,Sname,Cname,Grade
from TEST.Student,TEST.SC,TEST.Course
where Student.Sno=SC.Sno and SC.Cno=Course.Cno
再看一个例子:
select Student.Sno,Sname,Cname,Grade
from (TEST.Student left outer join TEST.SC on (Student.Sno=SC.Sno) )left outer join TEST.Course on (SC.Cno=Course.Cno)
这个例子是三个表的外连接,说明了 两个表连接之后看作是一个新的表即新的关系,使用这个关系连接新的关系。
【3.55】查询同系的同学(这个例子我做了修改改为查询同年龄的)
在此之前再次引入知识点:
嵌套查询参考文档
select Sno,Sname
from TEST.Student
where Sage in (
select Sage
from TEST.Student
where Sname='刘')
上面的例子中出现了嵌套这种查询,具体的过程类比于数据结构的二重循环,不再赘述。上面的例子中子查询与父查询是没有关系的,下面的[3.57]将介绍有关的查询。
其实这个也可以使用自然连接的方法,但是我觉得空间的消耗大
例【3.56】查询选修了课程号为特定的学科的学生的学号姓名
select Sname,Sno
from TEST.Student
where Sno in(
select Sno
from TEST.SC
where Cno in (
select Cno
from TEST.Course
where Cname='DB_i'
)
)
select 的属性是在from 中的关系里选择,如果有重复,需要使用‘.’操作符区分
【3.57】
select Sno,Cno
from TEST.SC x
where Grade>=(
select avg(Grade)
from TEST.SC y
where y.Sno=x.Sno
)
第二个例子想使用group by 语句甚至将SC表与Course连接之后使用,但是报错了。第一个例子的执行顺序是选择一个元组,选择学号属性,子查询中依据学号属性计算分数,因此是相关查询。个人的理解是相关查询是 类似于
下面的嵌套,需要使用父查询中数据。
for(int i=1;i<=10;i++){
for(int j=i;j<=10;j++){
}
}
【3.58】(这个例子做了修改,改为性别)
带有Any all 的子查询
any -->min 大于最小的一个
<any --<max 小于最大的
all 与any 相反不再赘述
select Sname,Sage
from TEST.Student
where Ssex<>'m'and
Sage <any(
select Sage
from TEST.student
where Ssex='m'
)
--非相关
这个例子是相当于<max的因此可以使用聚集函数
【3.59】
select Sname,Sage
from TEST.Student
where Ssex<>'m'and
Sage <all(
select Sage
from TEST.student
where Ssex='m'
)
相当于
select Sname,Sage
from TEST.Student
where Ssex<>'m'and
Sage <(
select min(Sage)
from TEST.Student
where Ssex='m'
)
总结
主要是对于连接查询,嵌套查询的使用。
连接查询使得可以从多个关系中查询数据,嵌套查询使得可以根据关系求解未知的数据,再根据信息进行查询。