当前位置:主页 > 查看内容

数据库6:连接查询和嵌套查询

发布时间:2021-07-12 00:00| 位朋友查看

简介:例3.42 查询每个学生及其选修课课程的情况 SELECT STUDENT . * , SC . * FROM STUDENT , SCWHERE STUDENT . SNO SC . SNO ; 当去掉 where 子句 这就是笛卡尔乘积 例3.50 对例3.49用自然连接完成 SELECT STUDENT . SNO , SNAME , SSEX , SAGE , SDEPT , CNO ,……

例3.42 查询每个学生及其选修课课程的情况

SELECT STUDENT.*,SC.*
FROM STUDENT,SC
WHERE STUDENT.SNO=SC.SNO;

在这里插入图片描述
当去掉 where 子句
在这里插入图片描述
这就是笛卡尔乘积

例3.50 对例3.49用自然连接完成

SELECT STUDENT.SNO,SNAME,SSEX,SAGE,SDEPT,CNO,GRADE
FROM STUDENT,SC
WHERE STUDENT.SNO=SC.SNO;

//若在等值连接中把目标列中重复的属性列去掉则为自然连接
在这里插入图片描述

例3.51 查询选修二号课程且成绩在九十分以上的所有学生的学号和姓名

SELECT STUDENT.SNO,SNAME
FROM STUDENT,SC
WHERE STUDENT.SNO=SC.SNO AND SC.CNO='2' AND SC.GRADE>90;

在这里插入图片描述

例3.52 查询每一门课的间接先修课(自身链接)

SELECT FIRST.CNO,SECOND.CPNO
FROM COURSE FIRST,COURSE SECOND
WHERE FIRST.CNO=SECOND.CPNO;

// FIRST 和 SECOND 是别名 自身连接相当于把一张表看成两张表 用别分分别表示 然后按照子句来查询
在这里插入图片描述

例3.53 外连接

SELECT STUDENT.SNO,SNAME,SSEX,SAGE,SDEPT,CNO,GRADE
FROM STUDENT LEFT OUTER JOIN SC ON (STUDENT.SNO=SC.SNO);

在这里插入图片描述

例3.54 查询每个学生的学号、姓名、选修的课程名及成绩

SELECT STUDENT.SNO,SNAME,CNAME,GRADE
FROM STUDENT,SC,COURSE
WHERE STUDENT.SNO=SC.SNO AND SC.CNO=COURSE.CNO;

在这里插入图片描述

嵌套查询

在这里插入图片描述

例3.55 查询与刘晨在同一个系的学生

//分两步 查询刘晨在那个系 再查找系里的学生
非嵌套查询

SELECT SDEPT
FROM STUDENT
WHERE SNAME='刘晨';
SELECT SNO,SNAME,SDEPT
FROM STUDENT
WHERE SDEPT='CS';

在这里插入图片描述

嵌套查询

SELECT SNO,SNAME,SDEPT
FROM STUDENT
WHERE SDEPT IN(
	SELECT SDEPT
	FROM STUDENT
	WHERE SNAME='刘晨');

在这里插入图片描述
子查询不依赖于于父查询 成为不相关子查询

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

// 首先在course关系中找出信息系统的课程号为3
然后在SC 关系中找出选修了三号课程的学生学号
最后在student关系中去除sno和sname

SELECT SNO,SNAME
FROM STUDENT
WHERE SNO IN(
SELECT SNO
FROM SC
WHERE CNO IN(
SELECT CNO
FROM COURSE
WHERE CNAME='信息系统')
);

在这里插入图片描述

例 3.57找出每个学生超过他自己选修课程平均成绩的课程号

SELECT SNO,CNO
FROM SC X
WHERE GRADE>=(
SELECT AVG(GRADE)
FROM SC Y
WHERE X.SNO=Y.SNO);

在这里插入图片描述
这里面 x代表外层 y代表内层 由于内层用到了外层 所以这是一个 相关子查询
类似于 双重循环

带有ANY(some)或ALL 谓词的子查询

在这里插入图片描述

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

SELECT SNAME, SAGE
FROM STUDENT
WHERE SAGE<ANY(
	SELECT SAGE
	FROM STUDENT
	WHERE SDEPT ='CS')
AND SDEPT !='CS';

在这里插入图片描述
或者用聚集函数
只要小于计算机系最大的学生的年龄就可

SELECT SNAME,SAGE
FROM STUDENT
WHERE SAGE<(
SELECT MAX(SAGE)
FROM STUDENT
WHERE SDEPT='CS')
AND SDEPT!='CS';

在这里插入图片描述

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

SELECT SNAME,SAGE
FROM STUDENT
WHERE SAGE<ALL(
SELECT SAGE
FROM STUDENT
WHERE SDEPT='CS')
AND SDEPT!='CS';

在这里插入图片描述
这个题也可以用聚集函数来做 道理是一样的 找到计算机系最小的学生即可

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

select Sname,Sno
from student 
where EXISTS(
		select *
		from SC
		where Sno=student.Sno AND Cno='1'
)

EXISTS 语句
相当于存在量词
EXISTI语句的返回值是 ture 或者false
EXISTS内部有一个子查询语句(SELECT … FROM…), 我将其称为EXIST的内查询语句。其内查询语句返回一个结果集。 EXISTS子句根据其内查询语句的结果集空或者非空,返回一个布尔值。
在这里插入图片描述
关于 in 和 exists 的区别
参考链接
in
确定给定的值是否与子查询或列表中的值相匹配。in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。所以相对内表比较小的时候,in的速度较快。

指定一个子查询,检测行的存在。遍历循环外表,然后看外表中的记录有没有和内表的数据一样的。匹配上就将结果放入结果集中。
看了别人对于in和exists区别的解释
觉得in是从子表和外表的笛卡尔积里选择正确的选项,而exists类似于双重循环 从外查询里选择一个和内查询里匹配

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

select Sname,Sno
from student 
where NOT EXISTS(
		select *
		from SC
		where Sno=student.Sno AND Cno='1'
)

在这里插入图片描述

例3.62 查询选修了全部课程的学生姓名

SQL中没有全称量词 all但是可以把带有全称量词的谓词转换为等价的带有存在量词的谓词y个学生及其选修课课程的情况

SELECT STUDENT.*,SC.*
FROM STUDENT,SC
WHERE STUDENT.SNO=SC.SNO

在这里插入图片描述当去掉 where 子句在这里插入图片描述这就是笛卡尔乘积

例3.50 对例3.49用自然连接完成

SELECT STUDENT.SNO,SNAME,SSEX,SAGE,SDEPT,CNO,GRADE
FROM SUTDENT.SC
WHERE STUDENT.SNO=SC.SNO;

//若在等值连接中把目标列中重复的属性列去掉则为自然连接在这里插入图片描述

例3.51 查询选修二号课程且成绩在九十分以上的所有学生的学号和姓名

SELECT STUDENT.SNO,SNAME
FROM STUDENT,SC
WHERE STUDENT.SNO=SC.SNO AND SC.CNO='2' AND SC.GRADE>=90;

在这里插入图片描述

例3.52 查询每一门课的间接先修课(自身链接)

SELECT FIRST.CNO,SECOND.CPNO
FROM COURSE FIRST,COURSE SECOND
WHERE FIRST.CPNO=SECOND.CNO;

// FIRST 和 SECOND 是别名 自身连接相当于把一张表看成两张表 用别分分别表示 然后按照子句来查询在这里插入图片描述

例3.53 外连接

SELECT STUDENT.SNO,SNO,SNAME,,SSEX,SAGE,SDEPT,CNO,GRADE
FROM STUDENT LEFT OUTER JOIN SC ON (STUDENT.SNO=SC.SNO);

在这里插入图片描述

例3.54 查询每个学生的学号、姓名、选修的课程名及成绩

SELECT STUDENT.SNO,SBANE,CNAME,GRADE
FROM STUDENT,SC,COURSE
WHERE STUDENT.SNO=SC.SNO AND SC.CNO=COURSE.CNO;

在这里插入图片描述

嵌套查询在这里插入图片描述## 例3.55 查询与刘晨在同一个系的学生//分两步 查询刘晨在那个系 再查找系里的学生非嵌套查询

SELECT SDEPT
FROM STUDENT
WHERE SNAME='刘晨';
SELECT SNO,SNAME,SDEPT
FROM STUDENT
WHERE SDEPT='MA';

在这里插入图片描述

嵌套查询

SELECT SNO,SNAME,SDEPT
FROM STUDENT
WHERE SDEPT IN(
SELECT SDEPT
FROM STUDENT
WHERE SNAME='刘晨';

在这里插入图片描述子查询不依赖于于父查询 成为不相关子查询

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

// 首先在course关系中找出信息系统的课程号为3 然后在SC 关系中找出选修了三号课程的学生学号 最后在student关系中去除sno和sname cSELECT SNO,SNAMEFROM STUDENTWHERE SNO IN(SELECT SNOFROM SCWHERE CNO IN(SELECT CNOFROM COURSEWHERE CNAME='信息系统'));在这里插入图片描述## 例 3.57找出每个学生超过他自己选修课程平均成绩的课程号cSELECT SNO,CNOFROM SC XWHERE GRADE>=(SELECT AVG(GRADE)FROM SC YWHERE X.SNO=Y.SNO);在这里插入图片描述这里面 x代表外层 y代表内层 由于内层用到了外层 所以这是一个 相关子查询类似于 双重循环# 带有ANY(some)或ALL 谓词的子查询在这里插入图片描述## 例3.58 查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名和年龄cSELECT SNAME, SAGEFROM STUDENTWHERE SAGE<ANY( SELECT SAGE FROM STUDENT WHERE SDEPT ='CS')AND SDEPT !='CS';在这里插入图片描述或者用聚集函数只要小于计算机系最大的学生的年龄就可cSELECT SNAME,SAGEFROM STUDENTWHERE SAGE<(SELECT MAX(SAGE)FROM STUDENTWHERE SDEPT='CS')AND SDEPT!='CS';在这里插入图片描述## 例3.59 查询非计算机科学系中比计算机科学系所有学生年龄都小的学生姓名及年龄sqlSELECT SNAME,SAGEFROM STUDENTWHERE SAGE<ALL(SELECT SAGEFROM STUDENTWHERE SDEPT='CS')AND SDEPT!='CS';在这里插入图片描述这个题也可以用聚集函数来做 道理是一样的 找到计算机系最小的学生即可## 例3.60查询所有选修了1号课程的学生姓名。sqlselect Sname,Snofrom student where EXISTS( select * from SC where Sno=student.Sno AND Cno='1')EXISTS 语句相当于存在量词EXISTI语句的返回值是 ture 或者false EXISTS内部有一个子查询语句(SELECT … FROM…), 我将其称为EXIST的内查询语句。其内查询语句返回一个结果集。 EXISTS子句根据其内查询语句的结果集空或者非空,返回一个布尔值。 在这里插入图片描述关于 in 和 exists 的区别参考链接in确定给定的值是否与子查询或列表中的值相匹配。in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。所以相对内表比较小的时候,in的速度较快。指定一个子查询,检测行的存在。遍历循环外表,然后看外表中的记录有没有和内表的数据一样的。匹配上就将结果放入结果集中。看了别人对于in和exists区别的解释觉得in是从子表和外表的笛卡尔积里选择正确的选项,而exists类似于双重循环 从外查询里选择一个和内查询里匹配## 例 3.61查询没有选修1号课程的学生姓名。sqlselect Sname,Snofrom student where NOT EXISTS( select * from SC where Sno=student.Sno AND Cno='1')在这里插入图片描述

标题例3.62 查询选修了全部课程的学生姓名SQL中没有全称量词 all但是可以把带有全称量词的谓词转换为等价的带有存在量词的谓词

在这里插入图片描述
相当于没有一门课程是他不选修的

SELECT SNAME
FROM STUDENT
WHERE NOT EXISTS
(
	SELECT*
	FROM COURSE
	WHERE NOT EXISTS(
		SELECT *
		FROM SC
		WHERE SNO=STUDENT.SNO
		AND CNO=COURSE.CNO
	)
);

在这里插入图片描述

例3.63 查询至少选修了学生201215122选修的全部课程的学生号码

在这里插入图片描述
不存在这样的课程y,学生201215122选修了y,而学生x没有选

SELECT DISTINCT SNO
FROM SC SCX
WHERE NOT EXISTS
(
	SELECT *
	FROM SC SCY
	WHERE SCY.SNO='201215122' AND
	NOT EXISTS
	(
		SELECT* FROM SC SCZ
		WHERE SCZ.SNO=SCX.SNO AND SCZ.CNO=SCY.CNO
	)
);

在这里插入图片描述
这个理解起来比较困难
把学生y作为学生201512122 学生x为你要寻找的学生
我的把他想象成一个三重循环 每次从scx里拿出一个学生x, 从scy里选出一个y学生选的课程,在第三个where里判断 x学生和y学生是不是都选修了这门课 如果都选修了话 第三层循环返回一个F给第二层 第二层返回给第一层 T 表面这门课y和x都选了
如果恰好y选的课x都选了
那么最后第一层的结果应该是若干个T 取或 最后的结果就是或
如果有一门课y选了 x没选
那么第三层循环会返回给第二册一个T 第二层再返回给第一层一个F 最后结果应该是T和F 取或 或者干脆都是F 取或 这两种结果最后都是F
说明y选的课X 没选
我是这么理解的 感觉应该是没有问题 如果有问题可以说出来
感觉这个exists是挺难的
以后得多写写

;原文链接:https://blog.csdn.net/Justafive/article/details/115614820
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!
上一篇:Windows10必备4款实用软件,我真的爱了 下一篇:没有了

推荐图文


随机推荐