case when 子查询_SQL之“多表查询”

02af32f78cf4a9fd474d925367d0220b.png

前几篇中我们查询的数据都是在一张表中进行操作的,但是实际工作中我们期望的数据往往分散在不同的表中,这时就需要下面我将写到的内容:从多张表中去获取数据。

一、表的加法

表的加法用英文单词表示:union,是将两张表的数据按行合并在一起。表的加法会把两个表中重复的数据删除只保留一个。如果想要保留两个表中重复的行,用union all 查询语句。

180d8d8083bfaed7608d944135a54864.png

练习:

9c30e75a824cd05bf09ef44754655119.png

二、表的联接

关系数据库里各个表之间如何建立起关系呢?

下图是4张表联接关系图,我们可以从中看出这4张表中的联接关系

095bac91983ee20322785bc3aa2b3b3b.png

表和表之间是通过列直接产生对应关系的,联接是通过表和表之间的关系将两个表合并在一起的操作,联接的类型有:

  • 交叉联接(cross join)

如图,cross join是将一个表中的每一行都与另一张表中的每一行合并在一起。交叉联接在实际业务中用得较少,因为结果数行太多了,需要花费大量设备的支持且没有什么实际价值。但它是其他联接的基础。

ceb7643faeea5a5d501a5e17f7f40e33.png

练习:

9cb6d21036e461e1e6634e644b8fb935.png
  • 内联接(inner join)

查找出同时存在于两张表中的数据。下图是内联接的联接过程:

3664d1e0e592852cd5b1fbecdcf9a296.png

7f72637e7ca52b662c3ceab0399f2ac7.png

我们看下内联接的SQL查询语句,有三个关键地方

  1. from子句中由原来的只有一张表变为两张表,且用as关键字对两张表起了别名方便我们使用。select子句中所选列都加了表的别名,表名是从特定表取出的列。
  2. from 子句中用inner join 将两张表联接起来。表明联接方式是内联接,选取出同时存在于两张表中的数据。
  3. from 子句中的关键字on 后表示两个表是通过哪个列匹配产生关系。

练习:

4f97a0482c85f73971a070e45382c16c.png
  • 左联接(left join)

左联接会把左侧表中的数据全部取出来。我们看下左联接在这两个表上是如何和运行的:

左联接会将左侧的表作为主表并全部取出,右边的表中只选出和左边表相同学号的行并进行合并。如果左侧表某行在右侧没有对应学号,相应列则为空值。

左联接的SQL查询语句只是将上述内联接语句中的inner join变为left join,其他不变。

ab09888fa12c6366907fb6f266fe4012.png

1b011f4a2985d388facb5d274b4cc885.png

再看一个问题,图片中红色区域如何表示呢?

356b07840ee29d3b9d890cad3521e9a3.png

它是在左联接的基础上去掉了两个表共同的地方。在原来的SQL语句中加入

“where b.学号 is null”表示右边表的学号为空值,这样就选出来左边表去掉公共部分的数据。

练习:

36fab3fd40bef6d07bfea2b68c9ed740.png

f01f989d348c9375f8ebf4e8eec9fba0.png

通过上图区别,我想提一下在这里要注意一个问题:

NULL表示不可知不确定,NULL不与任何值相等(包括其本身)
IS NULL 判断某个字符是否为空,并不代表空字符或者是0;
=NULL 是判断某个值是否等于NULL。 总之,要判断一个数是否等于NULL只能用 IS NULL 或者 IS NOT NULL 来判断
  • 右联接(right join)

右联接会将右侧表中的数据全部取出来。

a5ca28a336c7245f6a39788c1f945e89.png

19be1e13b7f796247893446da9ee0dee.png

练习:

0918648b8bb8eef15e3ad56fa900dcae.png

v2-f1f1692d3f00744701abb64768f7e122_b.jpg

同样在右联接的基础上再看一个问题,红色区域部分怎么表示呢,和左联接部分同理。

  • 全联接(full join)

全联接的查询结果会返回左右表中的所有行,当左右表的行有匹配时两个表会进行合并,若某一行与另一个表没有匹配时,另一个表对应的值用空值来填充。这样两个表中的数据就都在联接结果中了。

MySQL是不支持全联接的,这里理解下全联接概念即可。

总结:什么时候用哪一种联接呢?

当实际工作业务中,要生成固定行数的表单或特别说明了哪一张表里的全部数据时会使用左联接或右联接,其他情况都用内联接来获取两个表的公共部分。

两个表进行联接时在from 子句中加入联接语句,并不会影响SQL查询语句的运行顺序:

4e7116663b4eba21b08ff9b63768d64e.png

三、 联接应用案例

案例一:

查询所有学生的学号、姓名、选课数、总成绩

f869756458c2e6da644f23e5548fa4c6.png

案例二:查询平均成绩大于85的所有学生的学号、姓名和平均成绩

9b1c16fb88f139cbba0454d6ae5d7f9f.png

案例三:查询学生的选课情况:学号、姓名、课程号、课程名称

e45158eb56861bd5f0489f0d1f46033e.png

四、Case 表达式

使用case表达式可以帮助我们解决复杂的查询问题,它的作用相当于进行一个条件判断的函数,用来判断每一行是不是满足某个条件。

下图是case表达式的SQL语句,里面的when子句用来判断某行数据是否符合某个条件,如果符合条件就运行后面的then子句,case表达式也就此结束;如果不符合条件就进行下一个when子句。

8c783f665caefde92cfb2682ab85cdaf.png

如下图,要判断成绩及格或不及格就可以在select子句中用case表达式(注意:中间无逗号),并且给这列起了一个别名“是否几个”,会将查询结果放入里面。

对照下图可以看下此语句是怎样运行的:

61a625aa26c6c25da80cec3121f517f0.png

5f7b94f72a01c05705ea565b5aca3e42.png

接着再看下两个案例:

案例一:查询出每门课程的及格人数和不及格人数:

c062b045593c67382a88f2170ef61b75.png

注意事项:

  • else子句可以省略不写,这时会默认为else 为空值,但不建议省略。
  • end不能省略不写。
  • case表达式可以写到SQL语句的任意子句中。

案列二

使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计各分数段人数:课程ID和课程名称。(这种涉及到自定义的分组,妥妥的用case表达式)

4ce79ee326d4681545da1d10e1ef2801.png

这里要用课程号与课程名称两个列来分组,理由是:group by本来只用课程号就可以了,但是查询结果要我们显示出课程名称,我们学习group by 子句时select 里的列名只能是group by子句里的列名。为了让查询结果同时显示出课程名称,故group by 子句里加入了课程名称。这里加入的前提是不影响分组结果,如果影响分组的话就不能加了。

五.sqlzoo题目练习

6160037fcf895a43caa6deab0f2f9aac.png

24b2e1c5b0612a585c57beb8aed49600.png

b7e79a583612c384adb7b2cd7f0a028a.png

ace460fbfb03e624f393509b902bcbef.png

d7416d0898dbc6c985f562542e18228d.png

1eb02d7387a3c37dcd0aa2f3e8f05e9e.png

de6e796e4eacc592a5cfc4beb946f508.png

71c2dd82573fa7d0ffcc1357aa83df96.png

e3d6722e4107d1f141052ad06e51ced8.png

add00057dc0af5123ba4760921cda955.png

8a7212171f3ee4db434e615b2966aa8c.png

308f0685aa8ab839dcc4a29e274ec637.png

97cfc4d55e4f9d33132ff02740b8a64f.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值