SQL语句之数据查询(⼆)多表查询-----------------数据查询的重点难点
1.0 连接查询—多表查询
数据库已有的表和⾥⾯的内容
1. 等值连接与⾮等值连接
什么叫等值连接呢?
就拿上⾯的的student 表与 SC表来说 我们把他们合到⼀起 可以⽐较的列在⼀起进⾏⽐较,如果值相等,那么这列的元素所在的 ⾏就会合并
eg:
select student.* ,SC.* from student ,sc where student.Sno = Sc.Sno;
可以看出来 Sno 的值相等的⾏合并为⼀⾏了
sql自学难吗等值连接的过程是 我们在student表中的⼀个字段,去Sc表扫描每⼀⾏,满⾜条件就输出,知道扫描完成,
这是⼀种可能情况,也叫嵌套循环连接算法 我们可以⽤建⽴索引来提⾼效率
什么叫⾮等值连接呢?
还是上⾯的例⼦ 简单的来说就是满⾜不等条件的放在⼀⾏
select student.* ,SC.* from student ,sc where student.Sno > Sc.Sno;
⼀种可能的⽐较⽅法是 student中每⼀个Sno 的值与sc表的第⼀个元素⽐较 等student.Sno 的值都与Sc.sno 第⼀个值⽐较完成后,在与下⼀个值⽐较,以此类推 满⾜条件就是⼀⾏
为了满⾜接下来的例⼦ 插⼊数据后的三张表如下
eg: select student.,sc. from student,sc where student.sno>sc.sno;
数据我已经插⼊了,注意因为sc含有表级完整性约束 也就是外键 所以应该先插⼊course 在插⼊sc表,否则插不进去
⾄于原因很简单 既然SC表的cno 是参照course的,那么course要是没有cno与sc 相等的,那肯定差不进去呗
⾃然连接
我们在进⾏等值连接的时候 student.Sno 和sc.sno 数值是⼀样 显=显⽰两遍了 让他只显⽰⼀遍就是⾃然连接
select A.sno,A.sname,A.sex,A.sage,A.sdept,age from student A,sc B where A.sno = B.sno;
其中 A B 是分别起的别名
2. ⾃⾝连接
顾名思义 就是⾃⼰和⾃⼰连接 ,为了区分⽤到的是哪个⾃⼰ 要起别名
select A.sno,A.sname,A.sex,A.sage,A.sdept, B.sno,B.sname,B.sex,B.sage,B.sdept from student A,student B where A.sno > B.sno;
select A.sno,A.sname,A.sex,A.sage,A.sdept, B.sno,B.sname,B.sex,B.sage,B.sdept from student A,student B where A.sno = B.sno;
3.0 外连接 分为左外连接与右外链接
外链接与正常连接的区别是 通常的连接只会输出满⾜条件的连接 不满⾜的不会输出
例如上⾯的⾃然连接的例⼦中 学号为002的学⽣并没有显⽰出来 因为他不符合要求,左连接就是保留左边表的左右数据,连接的表如果没有就是null
语句格式是 left outer join 表明 on(..) ;
eg: select * from student left outer join sc on(student.sno = sc.sno);
右链接就是保存右表的所有数据 right outer join 表明 on();
4.0 多表连接 查询每个⼩学⽣的学号 姓名 年龄 性别 课程 课程号
select * from student a,sc b,course c where a.sno = b.sno and bo = co;
2.0 嵌套查询
在sql语⾔中 有个 select .. from … where .. 叫做查询块
把⼀个查询快放在另⼀个查询块的where或者 having⼦句中的查询叫做嵌套查询
1. 带有 in谓词的⼦查询
因为⼦查询出来的往往是⼀个集合,所以in是嵌套查询中最常⽤的谓词
例如:我们查询与xyd 在同⼀个系的学⽣
⼤致分为以下⼏步:
1.0 查询xyd在哪个系?
select Sdept from student where Sname = ‘xyd’;
结果是计算机科学与技术
2.0 查询这个系都有哪些学⽣
select Sname from student where Sdept = ‘计算机科学与技术’;
这样就查出来了 然后我们进⾏嵌套
select Sname from student where Sdept in(select Sdept from student where Sname = ‘xyd’) ;
⼦查询的条件与⽗查询⽆关 叫做不相关⼦查询
这件事也可以⽤连接查询来查询
select B.Sname from student A,Student B where A.sdept = B.sdept and A.sname = ‘xyd’;
这就涉及到数据库调优的知识了,由于嵌套查询的调优技术还没有成熟,所以我们能⽤连接查询就⽤连接查询2. 带有⽐较运算符的⼦查询
因为⼀般我们⼦查询的结果是个集合,索引要⽤in 但是当我们知道⼦查询的结果是单个值得时 就可以不⽤in了,可以⽤ < > = 等⽐较运算符运算
例如上⾯的例⼦select Sname from student where Sdept in(select Sdept from student where Sname = ‘xyd’) ; 我们查询的只能是⼀个值 所以就可以⽤ = 了
eg:变为select Sname from student where Sdept = (select Sdept from student where Sname = ‘xyd’) ;
上⾯我们讲了什么叫做不相关⼦查询,
如果⼦查询的查询条件与⽗查询有关就叫做相关⼦查询
eg:查询每个学⽣超过他选修课程平均成绩的课程号
select Sno,Cno from Sc x where Grade > (select avg(grade) from sc y where y.sno = x.sno);
上述SQL的⼀种可能执⾏过程是这样的
1. ⾸先查询x.sno 假设到的是1
2. 然后执⾏ select avg(grade) from sc y where y.sno = 1;
3. 假设结果设80
4. 然后执⾏ select Sno,Cno from Sc x where Grade > 80;
5. 回到1 到下⼀个 x.sno 假设2
6. 重复执⾏1-5 知道 x表中的Sno 全部查询完毕
我们看到⼦查询的y.sno 的值依赖于⽗查询的x.sno 这就叫做相关⼦查询
由此我们可以看出来 求解相关⼦查询的时候不能像不相关⼦查询那样⼀次性把⼦查询结果求出来,然后在求解⽗查询 因为相关⼦查询与⽗查询有关,所以必须反复进⾏⼦查询 ⽽不是⼦查询这次完事后就不⽤了
3. 带有any或者all 谓词的⼦查询
我们⽤⽐较运算符的时候,只能在返回值是⼀个的时候⽤,并且 单个值得时候 = 和in 的左右是⼀样的,但是你不能⽤ in 代替
< > 那返回多值得时候 假设返回的是1-100之间的数,但是我只想要⼤于结果集中所有数的怎么办呢?
这就是要带有any 和all 的⼦查询
any 和 all 什么意思怎么⽤呢? 看下表:
使⽤ any或者all的时候必须配合⽐较运算符 并且有的数据库不⽤any ⽤some
谓词解释
>any⼤于⼦查询结果集中的某个值
>all⼤于⼦查询结果集中的所有值
< any⼩于⼦查询结果集中的某个值
< all⼩于⼦查询结果集中的所有值
>=any⼤于等与⼦查询结果集中的某个值
>=all⼤于等与⼦查询结果集中的所有值
<=any⼩于等于⼦查询结果集中的某个值
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论