查询去除空值_SQL多表查询—知识点梳理(五)

本文详细介绍了SQL多表查询,包括表的加法、联结(内联结、左联结、右联结、全联结)的应用,以及case表达式的使用。通过实例解析了各种联结方式的原理和查询效果,特别是如何在查询中去除空值,提升查询效率。此外,还提供了多个实用的查询案例和联结操作的总结。
摘要由CSDN通过智能技术生成

64f0ef8bb99318ff77fab5e4b93c8394.png

SQL多表查询学习大纲

cc6173c958192e97b741db99883dad3a.png

一、表的加法

创建新的课程表course1

6e7eb55035a338f8abfb3249c0ef6012.png

union函数

表的加法,将两个表中的数据按行合并在一起,并删除重复的数据只保留唯一数据。

d524a78892199ab0973a56ff5283da92.png

union all函数

如果想保留重复行,在union后加上all即可

752ffd316c5ce4007ac67cf32b766083.png

合并两个表

打开客户端—右击course—“复制表”—“结构和数量”—右击新出现的course的复制表course_copy—重命名为course1—右击course1—“打开表”—将表中的数据修改为前面所示数据

a1b7264b0bc27c03e99ca2d261464907.png

f338299270be1b26b03c6c3af8280177.png

5d13361ccaba0f2b989188f3ab752772.png

然后输入两个表合并的SQL语句

4bdaa76fd1cbe1f36187aee24d26767e.png

二、表的联结

学生表和成绩表通过学号进行关联,关系就是数据库中能够对应的匹配,在关系数据库中叫联结(join)

d329265d5ae639c52b1f60b3be2494c0.png

2abeedf237b78a1c1164063a5cd71c57.png

bdd859feeae80f443f5b56e01eb454c1.png

常用的联结有五种类型:交叉联结(cross join)、内联结(inner join)、左联结(left join)、右联结(right join)、全联结(full join)。

e349409cd7e73044c21fcd10a9322b23.png

交叉联结(cross join)——笛卡尔积

将一个表中的每一行都与另一个表中的每一行合并在一起。

表1和表2进行交叉联结的过程:表1的第一行分别与表2中的每一行合并在一起,表1的第二行分别与表2中的每一行合并在一起...以此类推。交叉联结产生的表的行数是两张表行数的乘积。

9bd05fb49b4120c7f4459a602a8e0612.png

交叉联结最典型的案例—扑克牌

交叉联结在实际业务中应用较少,因为产生的结果行数较多,需要花费大量的运算成本和设备的支持,并且交叉结果行没有实际的价值。即便如此,交叉联结依然是后面所有联结的基础,其他联结是在交叉联结的基础上加上了过滤条件。

dae54e190470a7bc6c614dc971ca6672.png

内联结(inner join)

查找出同时存在于两张表中的数据。

f99e79b03764296a2f96f89eb0a3ebf8.png

c970fa78efa333f10fa766e1bd601889.png

学生表和成绩表进行内联结的过程:首先两个表通过学号进行内联结,然后取出两个表中都有的学号所在的行,最后将两个表里取出的数据进行合并(交叉联结),合并之后的表就拥有了两个表里的全部信息。

659a3565e4a0e3c839da8ded05e21f0a.png
        • 内联结对应的SQL查询语句

第一个关键之处在于from子句中,前面所学的from子句只有一张表,而现在在from子句中同时使用两张表,由于表名太长会影响SQL的可读性,因此通过as关键字对每个表起别名方便使用。在使用列名时为了区别列是来自哪个表,所以会在列名前加上表的别名并用“.”连接,因此在select子句中都加了表的别名

第二个关键之处在于from子句中,用inner join把两张表联结起来,表示内联结。选取出同时存在于两张表中的数据

第三个关键之处在于from子句中,关键字on后面表示是通过哪个列进行匹配联结来产生关系的

8b56f871a554400a450eda29c350be52.png

左联结(left join)

        • 进行左联结的过程

第一步:下图中两个表通过学号产生匹配,两个表进行左联结时会将左侧的表作为主表,并读取主表中的全部数据,右侧表中只选取出与左侧表学号相同的行

a7275f0ed70e9ffa7f65424f7d136822.png

第二步:把两个表取出的数据进行合并(交叉联结)。由于左侧表学号0002在右侧表没有对应的行,所以这一行对应的值为空值

1ea6b08338931dd800c22e3206e5a5a8.png
        • 左联结对应的SQL查询语句

在之前的SQL语句中修改inner join为left join,其余地方均相同

3e11591d2120d66b85a5abc82d76c2fe.png

在左联结的基础上还存在一个问题,如何表示下图红色部分?这是在左联结的基础上去除二者共有的部分

8aa802ba921c8e5f237a99b55b8f66a1.png

可以在前面的左联结SQL语句中,加入where子句“右侧表的学号为空值”

607539fe994272e4d2cb28b36ce7d1e3.png

右联结(right join)

        • 进行右联结的过程

第一步:两个表通过学号进行右联结,将右侧表中的数据全部取出,左侧表只选出与右侧表有相同学号的行

f61b021142ce3fe1e08a051e2c74b484.png

第二步:将两个表里取出的数据进行合并(交叉联结)。由于右侧表学号0005在左侧表没有对应的行,所以这一行对应的值为空值

b00fa535344b0e90e87a120ad8f43746.png
        • 右联结对应的SQL查询语句

在之前的SQL语句中修改left join为right join,其余地方均相同

774048da33cbd55a080baeb0740f0bb9.png

在右联结的基础上还存在一个问题,如何表示下图红色部分?这是在右联结的基础上去除二者共有的部分

28465f1f710661adacdfc95406aba2a6.png

可以在前面的右联结SQL语句中,加入where子句“左侧表的学号为空值”

ddc9efb0dc460aff5ac3d07797f4f050.png

全联结(full join)

全联结查询结果会返回左侧表和右侧表中的所有行

cd26eef21d5da0c46cc8ac7e9068cbf1.png

当母行和另一个表中有匹配时,会进行合并;若当母行和另一个表中没有匹配时,另一个表中对应的值用null进行填充。下图多了两行空值分别是左联结和右联结结果出现的空值,这样两张表的数据都在全联结结果中了。

值得注意的是,MySQL不支持全联结,只需了解全联结的概念即可。

bd5a1c0bc59b4b58e418614c91e07392.png

三、联结应用案例

817a321f81382dc47c36105edf6096f8.png
    • 案例1:查询所有学生的学号、姓名、选课数、总成绩

931d3c9427d856603c7fbd155cbbfa41.png

afd4162214c0182cce10601e83eeb614.png

012248d677221f58d1ad40da8a8c773f.png
    • 案例2:查询平均成绩大于85的所有学生的姓名和平均成绩

7abdc6fdc87122ab41e5350ea4536492.png

c43320b70d50ab92c68024df9e87d65a.png

c32e04dfacba7b0f55e3c839a8137e0e.png

d9153ccbe318e4421020b243b0f00f92.png

557fbe83eea0b9e0ddb89f668920be0c.png

29f1eb3c925ce1967c10bc5f30a10562.png
    • 案例3:查询学生的选课情况(三张表的联结)

8cb8cd877d77bdb59a10c2d3e9a9e454.png

5645023da8aa0417e28fa71f62196f6e.png

四、case表达式

使用case表达式有利于解决复杂的查询问题。case表达式的作用相当于进行一个条件判断的函数,用来判断每一行是否满足某个条件。

    • when子句的<判断表达式>用来判断母行数据是否满足某个条件:
      • 若符合条件就运行后面的then子句,case表达式就运行到此结束,不会再继续运行后面的when子句
      • 若不符合条件就进入下一个when子句
      • 如果直至最后都没有找到符合条件的when子句,那么就会运行else中的表达式。

748e9f7a40d688caec2cf5382a3fd2c5.png
    • 案例1

38c119f6a3ccab852500e6b92eb529b6.png

4abcf532614343584a8b650e8dcd5b66.png
    • 案例2

7f0c1e79d4f33ccfdff2db9edb0c44ab.png

72d69f74ae7194dfcffac9f2dd517b3a.png

902204b0bd7044302d5c428139a9da28.png

8753a8238a12b2c36aad87e1bd741ea5.png

902204b0bd7044302d5c428139a9da28.png

27c42accf4d396bf42d58ca1a44500cc.png
    • 案例3

b1ef8b479e3697e970e503acc1ea800e.png

第一步:from子句是联结两个表。因为要查找课程表里的全部数据,所以使用的是右联结

第二步:group by子句是对联结结果按课程号、课程名称来分组。之所以用两列来进行分组是因为原本可以只用课程号进行分组,但查询结果需要显示出课程名称,所以group by还加入了课程名称(此处可以加入分组的前提条件时必须不影响分组结果,因为一个课程号对应一个课程名称是一对一的关系,所以无论加入还是去除课程名称都对分组结果没有影响)。当group by子句有多个列分组时,只有这几个列的值全部都相同才算一组

第三步:select子句的查询结果。运用了case表达式和求和函数一起实现

114bab5703374e358076bbc1197304eb.png

注意事项

需要条件判断时可以使用case表达式,如涉及到自定义的分组问题:

1. else子句可以省略不写,此时默认else为空值,但为了更好的书写习惯建议不省略

2. 最后的end不能省略不写

3. case表达式可以写在SQL语句的任意子句里

75552415f1f6d0e66d0e8387602fb716.png

五、总结

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

9a778d6c168320ed1c575d8765095bc5.png

SQL运行顺序

      • 当有多个表进行联结时,是在from子句里加入的联结,不会影响前面所学的SQL运行顺序。
      • 首先当SQL查询语句里有子查询时,总是会先运行子查询
      • 其次先运行蓝框里的子句,蓝框里的子句按书写顺序运行
      • 然后再运行select子句
      • 最后运行红框里的子句,红框里的子句按书写顺序运行

1063458ff649eeeaaf5f7c5e1c876e11.png

六、练习

Chestnut-J:SQL多表查询—练习(五)​zhuanlan.zhihu.com
40381ed4d7de26be9ca56b365394c1a3.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值