子查询与内连接查询区别(效率上,连接查询高于子查询)、左连接以及连接的原理,还有内连接与左连接的区别
一、子查询与内连接查询区别(效率上,连接查询高于子查询)
❀①❀
子查询:比起连接查询慢点是:它取出表1 的第一行记录 ,就去与表2 的每一行记录进行比较,然后,它再取出表1 的第2行记录,去与表2 的每一行记录进行比较,又取出,然后与另外一个表的每一行记录进行比较,又取出,又与每一行记录比较,又取出。。。。。。
连接查询:直接取出表1所有记录与表2拼接到一起,然后在拼接后的同一张表再去比较,所以连接查询效率快。
语法:子查询:
select 列1,列2,(select 列3 from 表2 where 表1 与 表2 的共同属性) from 表1;
语法:内连接:
语法: select 列1,列2,列3… from 表1,表2,表3 where 表之间的共同属性。
或者:
select 列1,列2,列3… from (父表,(题意的主要数据来源))表1 inner join 表2 on (表1与表2 的共同属性)
表1 inner join 表3 on (表1与表3 的共同属性)
表2 inner join 表3 on (表2 与表3 的共同属性);
6,内连接与子查询的区别以及使用建议:
- 子查询的话,建议使用在查询显示出来的列只需要使用一张表的
- 内连接的话,建议使用查询显示出来的列需要使用到两张表中的多个列 (多表查询 适合用内连接)
❀②❀(暂时不看,因为这里成里的条件,我还没找到。。。。。)
打个比方:子查询好比小呆呆,它喜欢隔壁的小芳,想把山上那棵有99朵玫瑰的玫瑰,全部送给小芳,但是呢小呆呆,就跑上山上摘了一朵玫瑰,问小芳这朵玫瑰,她喜欢不,喜欢小芳就收下,就这样,小呆呆跑了99趟山上。小芳心里此刻就呵呵哒。。。
而连接查询就好比小李子拿了一个大花篮,一下子就把长了99朵玫瑰的玫瑰花摘到花篮里,哼着小曲,送到小芳面前,问道:小芳,这99朵玫瑰里,你喜欢哪一朵就留下哪一朵。此刻小芳心里乐开花了。。。
❀③❀
内连接题目:
数据库结构:(年级表、学科表、学生表、成绩表)
#内连接,查询学号(学生编号)、姓名、年级名称、学科名称、成绩
where+and :
#内连接,查询学号、姓名、年级名称、学科名称、成绩
select stu.StuId,StuName,GradeName,SubjectName,Score from stu,grade,subject,score
where stu.StuId = score.StuId
and grade.GradeId=stu.GradeId
and grade.GradeId=subject.GradeId
and subject.SubjectId=score.SubjectId;
inner join:
select stu.StuId,StuName,GradeName,SubjectName,Score from score # from 关联表1
inner join stu on stu.StuId=score.StuId #inner join 关联表2 (找出关联表2 与表1 的共同属性)
inner join grade on grade.GradeId=stu.GradeId #inner join 关联表3 (找出关联表3 与表1、表2 的共同属性)
inner join subject on subject.SubjectId=score.SubjectId and grade.GradeId=subject.GradeId; #inner join 关联表4 (找出关联表4 与表1、表2、表3 的共同属性)
❀④❀
左连接:
(1)左表与右表
① 左表:记录全部显示出来
② 右表符合条件的记录会显示,左表多余部分(在右表中找不到符合条件对应的数据),则右表数据写null.
(2)意义:对比两个表的差异,查询缺失信息—得到没有
(3)语法:
select 列1,列2,列3 from 左表
left join 右表 on (右表与 左表 的共同属性)
例如:#查询缺考学生信息
把(查到的学生信息对应考试信息,出现null,当做一个临时表)
#查询缺考学生信息
select StuId,StuName from(
#学生表与成绩表的左连接,可以得到学生信息对应考试表,出现考试信息为null
select stu.StuId,StuName,Score from stu
left join score on stu.StuId=score.StuId) where score is null;
报错:
报错:Every derived table must have its own alias
翻译报错:每个派生表必须有自己的别名。
解决: 给临时表(派生表)起个别名。
#查询缺考学生信息
select StuId,StuName from(
#学生表与成绩表的左连接,可以得到学生信息对应考试表,出现考试信息为null
select stu.StuId,StuName,Score from stu
left join score on stu.StuId=score.StuId) as 考试信息 where score is null;
❀⑤❀
ps:两张表的共同属性关系是:1对多,不适合用内连接。
内连接需要一张表与另一张表的共同属性是1对1,而不是1对多;(1:多只能选择子查询)。
举例子:表结构如下:
题意:查询显示出结果如下:
分析:
内连接查询:
因为参赛队表中的 队伍编号 同时被赛程表中的 主队编号 和 客队编号 引用作为外键,所以通过队伍编号的把两张表连接到一起,无法统一队伍编号是要与主队编号结合成一组还是和客队编号结合成一组。(1对多 的外键引用关系不适合用内连接!)
-----------不过通过,给表起别名区分开(实现了一对一),也是可以使用内连接的。
1、子查询:
#子连接
select (select TeamName from Team where `Match`.HostTeamId=Team.TeamId) as '主队',
MatchResult as '比分',
(select TeamName from Team where `Match`.GustTeamId=Team.TeamId) as '客队',
from `Match`;
2、2-1 起别名实现1对1的内连接:
#内连接
select Team.TeamName as '主队',MatchResult as '比分',t.TeamName as '客队',MatchTime as '比赛时间'
from Team, `Match`, Team as t where Team.TeamId=`Match`.HostTeamId and t.TeamId=`Match`.GustTeamId; # t 是Team 这张表起的一个别名,有“副表”的作用的意思
2-2 内连接写法2:
#内连接写法2
select Team.TeamName as '主队',MatchResult as '比分',t.TeamName as '客队',MatchTime as '比赛时间' from `Match`
inner join Team on (Team.TeamId=`Match`.HostTeamId)
inner join Team as t on (t.TeamId=`Match`.GustTeamId);
3、内连接跟子查询结合起来使用
3-1.写法一:
select Team.TeamName as '主队',MatchResult as '比分',
(select TeamName from Team where `Match`.GustTeamId=Team.TeamId) as '客队',MatchTime as '比赛时间'
from Team, `Match` where Team.TeamId=`Match`.HostTeamId;
3-2.写法二:
#内连接inner join结合子查询
select TeamName as '主队',MatchResult as '比分',(select TeamName from Team where Team.TeamId=`Match`.GustTeamId),MatchTime as '比赛时间' from `Match`
inner join Team on Team.TeamId=`Match`.HostTeamId;
❀⑥❀
二、左连接以及连接的原理
连接原理:
ps:所谓的内连接呀,左连接,右连接(连接)
例如 select 列1,列2,列3 from A 表
inner join B 表 on (B 表 与 A 表的共同属性) #连接后变成AB表
inner join C 表 on (C 表 与 AB 表 的共同属性) #连接后变成ABC 表
连接原理是 “A” 表 inner join “B” 表,即 “A” 表与 “B” 表连接成 “AB” 表,然后如果还 inner join C 的话,则是“AB” 表 与 “C” 表连接成 “ABC” 表。
❀⑦❀
三、内连接与左连接的区别:
1,内连接:
2,左连接:
对比看到,
内连接的拼接必须是你有,我有,才能拼接到一起。即把表A、表B共同部分拼接,而我有,你没有,为了求同就把我的独特给舍弃了。
左连接,是在连接的基础上,实现了我有你没有时,我显示的时候,你用null对应。
作者:一乐乐