SQL连接查询和嵌套查询详解
连接查询
若⼀个查询同时涉及两个或两个以上的表,则称之为连接查询。连接查询是数据库中最最要的查询,
包括:
1、等值连接查询
2、⾃然连接查询
3、⾮等值连接查询
4、⾃⾝连接查询
5、外连接查询
6、复合条件查询
等值与⾮等值连接查询:
⽐较运算符主要有=、>、<、>=、<=、!=(或<>)等。
下⾯来看⼀个例⼦:
假设有⼀个学⽣数据库,其中有三张表,即学⽣信息表(Student)、课程表(Course)、选课表(Study),三张表中的信息如下:
例1:要求查询选修了课程的学⽣的信息
很显然,需要⽤连接查询,学⽣的情况存放在student表中,学⽣的选课情况存放在Study表中,所以查询实际涉及Student和Study这两个表。这两个表之间的联系是通过公共属性Sno实现的。
考虑下列等值连接查询语句
SELECT Student.*,Study.*
FEOM Student,Study
WHERE Student.Sno=Study.Sno /*将Student与Study中同⼀学⽣的元祖连接起来*/
得到的结果:
我们发现,上述查询语句按照把两个表中学号相等的元祖连接起来。
系统执⾏的连接过程:⾸先在表Student中到⼀个元祖,然后从头开始扫描Study表,逐⼀查与Student第⼀个元祖的Sno相等的元祖,到后就将Student表中的第⼀个元祖与该元祖拼接起来,形成结果表中的⼀个元祖,Stdudy表全部查完后,再Student中的第⼆个元祖,
重复上述过程,直⾄Student表中的全部元祖处理完。
⾃然连接:在等值连接中把⽬标中重复的属性列去掉的连接查询
下⾯考虑⽤⾃然连接实现上述例⼦:
SELECT Student.Sno,SName,SSex,Sdept,Cno,Grade
FROM Student,Study
WHERE Student.Sno=Study.Sno
结果:
sql left join 多表连接⾃⾝连接查询:当查询的结果涉及同⼀个表中两个或以上的列时,考虑⽤⾃⾝连接查询
例2:查询每⼀门课的间接先⾏课(即先⾏课)
SELECT C1.Cpno
FEOM Course AS C1,Course AS C2 <span > </span>--为Course表起两个别名C1、C2
WHERE C1.Pcno=C2.Cno --两个Course表的连接
结果:
外连接查询:
分为左外连接,右外连接,
左外连接:根据左表的记录,在被连接的右表中出符合条件的记录与之匹配,不到匹配的,⽤null填充 右连接:根据右表的记录,在被连接的左表中出符合条件的记录与之匹配,不到匹配的,⽤null填充
例3:查询缺少成绩的的学⽣号和课程号:
SELECT Student.Sno,Cno
FROM Student
LEFT JOIN Study
ON Student.Sno=Study.Sno
WHERE Grade IS NULL
结果:
例4:查询所有学⽣的学号姓名、成绩
--左外连接
SELECT Student.Sno AS 学号,SName AS 姓名, Grade AS 成绩
FROM Student
LEFT JOIN Study<span > </span>
ON Student.Sno=Study.Sno
相当于:
--右外连接
SELECT Student.Sno AS 学号,SName AS 姓名, Grade AS 成绩
FROM Study
RIGHT JOIN Student
ON Study.Sno=Student.Sno
结果:
左外连接列出左边关系,右外连接列出右外关系中所有的元祖
多表连接查询:
--1、WHRER 语句
--2、INNER JOIN.. 语句
例:查询选修了C601号课程的学⽣姓名、分数、课程名
这个查询三个涉及了表学⽣表、课程表和学习表’
SELECT Student.SName AS 学⽣姓名,Grade AS 成绩,CName AS 课程名
FROM Student
INNER JOIN Study ON Student.Sno=Study.Sno
INNER JOIN Course ON Study.Cno=Course.Cno
WHERE Course.Cno='C601'
相当于⾃然连接查询:
SELECT Student.SName AS 学⽣姓名,Grade AS 成绩,CName AS 课程名
FROM Student,Course,Study
WHERE Student=Study.Sno AND Studyo=Course.Cno ADN Course.Cno=C601
嵌套查询
嵌套查询⼜称⼦查询,是指在⽗查询的where条件语句中再插⼊⼀个⼦查询语句,连接查询都可以⽤⼦查询完成,反之不然。
例1:出⾄少⼀门课程的成绩在90分以上的⼥学⽣的姓名
分析:已知的是分数⼤于90分这个条件,通过这个条件出Study表中⼤于90分所对应的Sno,再通过连接查询Study表中对应Sno的SName SELECT SName
FROM Student
WHERE Sex='⼥' AND Sno NOT IN
(
SELECT Sno
FROM Stduy
WHERE Grade<90
)
注意:这⾥⼦查询返回的Sno可能有多个,所以要⽤到谓词 IN,如果⽤ =,则报错,因为 = 表⽰⼦查询的返回值是唯⼀的。
⼦查询的⼀个原则:根据已知得出未知
例2:查询选修了课程名为 ‘’⾼等数学” 的学⽣学号和姓名
根据Course表中的⾼等数学得到课程号,再在Study表中到选修了该课程号的学号,最后根据学号Sno在Student表中出对应的学⽣的姓名。⼀层层嵌套,由已知得到未知。
SELECT Sno,SName
FROM Student
WHERE Sno IN
(
SELECT Sno
FROM Study
WHERE Cno IN
(
SELECT Cno
FROM Course
WHERE CName='⾼等数学'
)
)
相当于连接查询:
SELECT Student.Sno,SName
FROM Student,Course,Study
WHERE Student.Sno=Study.Sno AND Course.Cno=Study.Cno AND Course.CName='⾼等数学'
结果:
例3:出⾄少学了C601和C602两门课程的学⽣姓名。
这⾥涉及到两门课程,都来⾃Course表,涉及到同⼀个表中两个或以上的元祖,考虑⼦查询⽤⾃⾝连,⼦查询根据课程号返回学号,⽗查询再根据学号查询姓名。
SELECT SName FROM Student
WHERE Sno IN
(
SELECT Study1.Sno
FROM Study AS Study1
JOIN Study AS Study2
ON Study1.Sno=Study2.Sno
WHERE Study1.Cno='C601' AND Study2.Cno='C602'
)
结果:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论