此博客连接:https://www.cnblogs.com/ping2yingshi/p/13871481.html
数据库表间关联
说明
数据库的表间关联中,一共有以下四种方法。
1.内连接
定义:内连接使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行。
2.外连接
定义:外连接分为左联和右联。
左联:左联的结果集包括left outer 子句中指定的左表的所有行,如果左表的某行在右表中没有匹配的行,则在结果集中为右表所有列返回null。
右联:右联的结果集包括right outer 子句中指定的右表的所有行,如果右表的某行在左表中没有匹配的行,则在结果集中为左表所有列返回null。
3.笛卡儿积
笛卡儿积是内联中没有where子句,返回所有数据行的笛卡儿积,其结果中的行数等于第一个表中符合查询条件的行数乘以第二个表中符合查询条件的的行数(假设只有两个表)
4.自连接
定义:在一条select语句中不止一次地引用相同的表。
背景
有两个表,一个学生表,一个成绩表。
说明:每个学生在成绩表中只有对应一个成绩。
表结构如下:
学生表中包括学生姓名,学生ID。
成绩表中包括学生ID和学生成绩。
表数据如下:
学生表数据如下:
成绩表数据如下:
表数据解释:
一共有5个学生,考试时只有三个学生去考试,有两个学生弃考了,没有成绩。
问题
1.老师想查看每名学生的成绩(要求显示学生姓名和成绩)。
2.老师想知道谁参加了考试(要求显示学生姓名和成绩)。
3.老师紧急安排学生打扫卫生,让学生ID(stu_ID)小于班长(小红)的同学去打扫卫生。
实现问题1
方法1左联实现
左联使用情况
当有两张表时,需要先返回左表某个字段的所有行,再加上符合连接条件的匹配行。
分析
老师想获取所有学生的成绩,在成绩表中只有部分学生的成绩,所以应该先从学生表中把所有学生先查出来,然后再查成绩表,这种情况下可以使用左联,学生表左联成绩表,先查询所有学生的姓名,然后再查成绩表中的学生成绩。
代码
SELECT stu_Name,score FROM student LEFT JOIN score on student.stu_ID=score.stu_ID
查询结果
显示所有学生姓名,只显示成绩表中有的学生成绩,没有成绩的显示Null。
方法2 右联实现
右联使用情况
当有两张表时,需要先返回右表某个字段的所有行,再加上符合连接条件的匹配行。
分析
老师想获取所有学生的成绩,在成绩表中只有部分学生的成绩,所以应该先从学生表中把所有学生先查出来,然后再查成绩表,这种情况下可以使用右联,成绩表右联学生表,右联中先从学生表中查询所有学生的姓名,然后再查成绩表中的学生成绩。
备注
查询两张表时,当使用左联查询时,两张表的位置互换一下,就可以使用右联查询,查询结果和左联查询结果是一样的。
代码
SELECT stu_Name,score FROM score RIGHT JOIN student on student.stu_ID=score.stu_ID
查询结果
显示所有学生姓名,只显示部分学生成绩。
实现问题2
内联实现问题2
内联使用情况
当有两张表,只有在两个表中条件都满足才返回满足条件的数据。
分析
老师想查看谁参加了考试,参加考试的学生成绩在成绩表中,查询成绩表就可以查到谁参加了考试,但是成绩表中没有学生姓名,学生姓名需要到学生表中查询,使用内联,查询参加考试的学生姓名。
代码
SELECT stu_Name FROM score INNER JOIN student on student.stu_ID=score.stu_ID
查询结果
小白,小蓝和小绿去参加了考试。
笛卡儿积出现情况
说明
当查询数据,没有使用限定条件时,会产生笛卡儿积。
分析
在上面查询谁参加了考试,如果没有限定学生表中的学生ID等于成绩表中的学生ID条件时,会出现笛卡儿积的结果,返回两个表中符合条件的行数乘积。
代码
SELECT stu_Name,score FROM score INNER JOIN student
结果
学生表中一共有5名学生,成绩表中有三个成绩,所以得到15条记录。
实现问题3
自连接实现问题3
自连接使用情况
在一条sql语句中,一张表自己需要查询自己。
分析
老师首先需要在学生表中找到班长小红的学生ID,然后再在学生表中找学生ID小于小红学号的学生。两次都需要用到学生表,使用自连接。
代码
SELECT b.stu_ID,b.stu_Name from student a,student b where a.stu_Name='小红' and b.stu_ID<a.stu_ID
查询结果
学生ID小于小红的是小白和小蓝。