SQL 基础(六)多关系连接查询
多关系表连接查询
连接查询:一个查询需要对多张表操作,查询结果称表之间的连接;连接关系通过字段值体现,称为连接字段
当我们查询的数据、字段值分布在不同的表中时,这种情况下需要使用多关系表的连接查询
连接类型:内连接(INNER JOIN)、外连接(OUTER JOIN)、交叉连接()、自然连接()
连接谓词:连接两个表的条件
内连接查询
关键字(INNER JOIN),功能:仅返回连接条件为真的行,有
from
和where
字句两种方式
这里要注意,两张表连接时,同名属性需要使用前缀区分(列名唯一不需要)
实现内连接的三种方式举例:
1 | -- method1 |
以上方法中,method1 比较简单且常用 ,建议重点掌握
两张表连接
查询每位学生及选修课程信息
1.from 子句实现
1 | select * |
以上代码可简化为
1 | select * |
执行结果中发现存在相同列(学号),说明为等值连接,未删去重复列
2.where 子句实现
1 | select * |
查询每名同学成绩,包含学号,课程编号,成绩,课程名称信息
1 | select sno,sc.cno,cn,score |
多张表连接
1.from 子句
1 | select s.sno,sn,cn,score |
2.where 子句
1 | select s.sno,sn,cn,score |
外连接查询
外连接中,符合连接条件的数据返回到结果集,不符合连接条件的列会被系统用 NULL
填充,再返回结果集
*注:bit
类型无 NULL
值,会填充 0 后返回结果集中
使用主表所在的方向位置判断连接类型,例如:主表在左,即为左外连接
复习下关系运算中,连接的相关知识
那么上图两张表分别进行外、左外、右外连接后的结果为
举例:查询所有学生选课情况,包括未选课学生信息
左外连接 left join
1 | -- left join |
右外连接 right join
1 | -- right join |
完全外连接 full join
1 | -- full join |
交叉连接查询
又称 “笛卡尔乘积” 连接,实际应用中很少使用
考虑到计算机性能,执行效率也不大相同
这里主要知道关键字为 CROSS JOIN,结果集行数为两张表行数乘积,列数为两表列数总和,然后参考下下方示例即可
1 | -- 对学生表和成绩表进行 交叉查询 |
自连接查询
如果我们要查询的结果集中,所包含的信息均在同一张信息表中,这样的查询方式称为自连接查询
示例:查询工资表中,所有比 XXX 工资高的同事姓名、工资和 XXX 的工资
1 | -- method1 |
子查询
又称嵌套查询,形式是在 WHERE 中再次包含 SELECT - FROM - WHERE 的查询
程序从内向外执行 SQL 语句,外部查询称为父查询,父查询需要接收子查询(嵌套查询)的结果
普通子查询
普通子查询仅执行一次
返回一个值
该例子解释父级查询需要子查询结果的概念
1 | select tno,tn |
示例中,prof
的值由子查询查出结果后返回给父查询做结果,上述语句等价为
1 | select tno,tn |
返回一组值
比较运算符仅适用于查询所需返回值为单个值得情况,当返回结果为集合时不再使用,可使用如下方式
ANY
ANY:任何一个
示例:查询讲授课程号为 c5 的教师姓名
1 | select tn -- 姓名 |
首先执行子查询,找到讲授 c5 课程的教师号,父级查询根据教师号再查询教师姓名
意思是,tno
是子查询结果集中的任(ANY)一个
IN
和 ANY 一样的例子,我们也可以使用 IN 实现
1 | select tn -- 姓名 |
这里的意思是,tno
在(IN)子查询结果集中
ALL
ALL:全部
示例:查询其他系中比计算机系所有教师工资都高的教师姓名和工资
1 | -- 使用 ALL |
相关子查询
由上面的内容我们知道,子查询程序执行顺序是由内到外,也就是说父级需要子级的消息返回
但是,我们同样会遇到子查询需要父查询相关信息的情况,这样的情况我们称之为相关子查询
示例:查询不讲授课程号为 c5 的课程的教师姓名
1 | -- method1 <> ALL |
该例中,子查询判断课程号 cno 时,需要数据表 t 中教师号 tno 信息,为相关子查询
集合运算查询
在各个子查询对应数据条目和数据类型一致的条件下,可以使用 UNION
关键字将不同的查询得到的数据组合起来
且 UNION
会自动删除重复数据行
使用方法比较简单,给出一个例题供参考
1 | select sno,sum(score) |
上面的 SQL
语句实现:将从 tb_a
中查询出学号为 001 同学的学号和总成绩信息和从 tb_b
中查询出学号为 002 同学的学号和总成绩信息合并为一个结果集
存储查询结果
此处“存储”的含义是指将 A 表中查询的数据结果集存储到其他表,B 表中
我们使用 SQL 语句查询到的结果,仅临时导出让用户(我们)看到,并未真正影响(存储)到对应数据库中,那如何实现查询结果的存储呢?
语法格式为:
1 | SELECT ... INTO ... |
具体实现如下
1 | selelct sno,sum(score) -- 学号,总成绩 |
上面的 SQL
语句实现从 tb_a
中查询出学号和总成绩信息并存放到 tb_b
表中