SQL Server 查询语句(二)
连接查询
多表连接查询、单表连接查询(自连接)、外连接查询、复合条件连接查询.
示例数据表:
学生信息表Student; 课程信息表Course; 选课情况表SC,教师信息表teacher
1--- 单表连接(自连接)
用表别名把一个表定义为两个不同的表进行连接。
2--- 左连接、右连接、全外连接
求各部门名及职工名,要求输出无职工的部门(职工以空值出现)
SELECT DNAME,TNAME FROM department D,teacher T
WHERE D.DNO = T.DNO(*);(有*则,别表示该列可以为空 Left join )
求各部门名及职工名,要求输出无职工的部门和未分配部门的职工
SELECT DNAME,TNAME FROM department D,teacher T
WHERE D.DNO (*) = T.DNO(*);(Full join )
3--- 复合条件连接
嵌套查询
在SELECT …FROM …WHERE语句结构的;
WHERE子句中可嵌入一个SELECT语句块;
其上层查询称为外层查询或父查询;
其下层查询称为内层查询或子查询;
SQL语言允许使用多重嵌套查询;
在子查询中不允许使用ORDER BY子句;
嵌套查询的实现一般是从里到外,即先进行;
子查询,再把其结果用于父查询作为条件。
1--- 返回一组值得子查询
求选修‘C6‘课程且成绩超过分的学生
SELECT * FROM student
WHERE sno IN ( SELECT sno FROM SC WHERE Cno='C6' AND Grade>);
求比计算机系中某一学生年龄小的其他系的学生
SELECT * FROM student
WHERE sdept!=’CS’AND sage <ANY( SELECT Sage FROM Student WHERE Sdept=‘CS’);
带有EXISTS的相关子查询
不相关子查询:子查询的查询条件不依赖于父查询的称为不相关子查询。
相关子查询:子查询的查询条件依赖于外层父
查询的某个属性值的称为相关子查询(Correlated Subquery),带EXISTS的子查询就是相关子查询
EXISTS表示存在量词,带有EXISTS的子查询不返回任何记录的数据,只返回逻辑值‘True ’或‘False ’
例:求所有选修了‘C1’课程的学生名。
不相关子查询
SELECT Sname FROM student
WHERE sno IN ( SELECT sno FROM SC WHERE Cno = 'C1' );
相关子查询
SELECT Sname FROM student
WHERE EXISTS
(
SELECT * FROM SC
WHERE student.sno=SC.sno AND Cno='C1'
);
先在外层查询中取student表的第一个元组(记录),用该记录的
相关的属性值(在内层WHERE子句中给定的)处理内层查询,若
外层的WHERE子句返回‘TRUE’值,则此元组送入结果的表中。然
后再取下一个元组;重复上述过程直到外层表的记录全部遍历一次为止。
不关心子查询的具体内容,因此用SELECT *, Exists + 子查询用来判断该子查询是否返回元组
当子查询的结果集非空时,Exists为'True'; 当子查询的结果集为空时,Exists为'False'
NOT EXISTS :若子查询结果为空,返回‘TRUE’值,否则返回‘FALSE’
例:列出没有选C1课程的学生的学号、姓名
SELECT Sname FROM student
WHERE NOT EXISTS
(
SELECT * FROM Course
WHERE student.sno=SC.sno AND Cno='C1'
);
例:查询选修了所有课程的学生的姓名
SELECT Sname FROM student
WHERE NOT EXISTS
(
SELECT * FROM Course
WHERE NOT EXISTS
(
SELECT * FROM SC
WHERE student.sno=SC.sno AND Course.Cno=SC.Cno
)
); /*该学生不存在于 所有课都选的学生的集合之中*/
例:名查询至少选修了S1所选的全部课程的学生
SELECT Sname FROM student
WHERE NOT EXISTS
(
SELECT * FROM SC SCX
WHERE SCX.sno='s1' AND NOT EXISTS
(
SELECT * FROM SCSCY
WHERE student.sno=SCY.sno AND SCX.Cno=SCY.Cno
)
); /*该学生不存在于 S1所有课都选的学生的集合之中*/
注意细节
在FROM语句中使用子查询,对查询结果定义表名及列名
SELECTSno, AVG_G
FROM (
SELECTSno,AVG(Grade) FROM SC
GROUP BY Sno
) AS RA(Sno,AVG_G)
WHERE AVG_G>80;