数据产品经理养成记(四):SQL多张表查询

上一节讲了SQL简单查询,包括SQL语句的分类、基本查询语句(select)、条件语句、运算符等。本节讲一下多表查询。

数据产品经理养成记(四):SQL多张表查询_第1张图片

举个工作中的实际例子,假设你在做一款贷款产品,这里有两张表:用户表(userinfo)、借款还款表(loanapp)。你想查询所有用户的借款总笔数、借款总金额,就需要以用户作为关联条件,从三张表里面查找相应的数据进行分析。具体如何实现?看完下面的内容你就能轻松解决这个问题。

1.表的加法

表的加法是指按行,将表合并在一起,通过关键字union实现。现在,这里有两张格式一样的表,你想把两张表的数据合并起来,该如何操作?

数据产品经理养成记(四):SQL多张表查询_第2张图片

先写语句再解释,如下:

select 学生姓名,学生编号 --注释:选择course1表的两列数据

from 表1

union--注释:合并

select 学生姓名,学生编号 --注释:选择course1表的两列数据

from 表2;

运行结果如下:

数据产品经理养成记(四):SQL多张表查询_第3张图片

注意

表1 中有两行数据,表2 中有三行数据,加起来是五行数据,但是运行出来的结果只有四行数据。这是因为关键字【union】会把表里面重复的数据去重。如果你想保存重复的行,将【union】改为【union all】即可。

2.表的联结

之前介绍过,关系数据库中,表和表之间是通过关系列关联起来的(哪里都要靠这种关键节点,数据库中是,生活中也是这样,有关系好办事。。。)

数据产品经理养成记(四):SQL多张表查询_第4张图片

有了关系列后,就可以把不同的表联结起来,常见的联结方式有以下几种:

交叉联结、内连接、做链接、右联结、全联结,我们逐一介绍。

交叉联结(cross join)

又称为笛卡尔积,作用是将一个表中的每一行,和另一个表中的每一行合并在一起。交叉联结后的总行数,是两张表的行数的乘机,举个例子:

数据产品经理养成记(四):SQL多张表查询_第5张图片

两个表交叉联结后的结果如下:

数据产品经理养成记(四):SQL多张表查询_第6张图片

可以看到,联结后的展示的内容,是将两个表的内容拼起来。表的行数是两张表的行数的乘机:1*2=2.如果第一张表有5行,第二张表有3行,那么两张表交叉联结后的行数为:5*3=15.

说明:

交叉联结在实际业务中用的比较少,因为交叉联结产生的数据太多了,需要耗费很多设备、时间成本计算。而且,交叉联结会产生很多无意义的数据。但是,交叉联结是我们接下来要说的几种联结方式的基础,因此还是有必要了解清楚。

内联结(inner join)

作用是选取出同时存在于两张表中的数据,选取后按照交叉联结的方式合并展示出来。

数据产品经理养成记(四):SQL多张表查询_第7张图片

举个例子,现在有两张表,如下:一张学生信息表,一张学生成绩表,现在你想查出某个学生的信息和成绩,如何用inner join实现?

数据产品经理养成记(四):SQL多张表查询_第8张图片

这里先写语句:

select学生信息表.学号,学生信息表.姓名,学生成绩表.学号,学生成绩表.课程,学生成绩表.成绩--选择要拼接的列,为了方便区别这个列是哪张表的,需在列名前边加表名

from学生信息表inner join学生成绩表--选择拼接的表

on学生信息表.学号 = 学生成绩表.学号;--选择以哪个列作为拼接条件

上面两张表的名称太长,不管在书写还是在阅读上都不方便,能不能给它们起一个临时名称,以方便书写?这里可以用关键字as来实现,写法如下;

select a.学号,a.姓名,b.学号,b.课程,b.成绩--选择要拼接的列,为了方便区别这个列是哪张表的,需在列名前边加表名

from学生信息表as a inner join学生成绩表as b--选择拼接的表

on a.学号 = b.学号;--选择以哪个列作为拼接条件

通过以上语句,运行处的结果如下:

数据产品经理养成记(四):SQL多张表查询_第9张图片

说名

内联结的SQL 语句运行顺序如下:

- 将两个表里面【学号】相同的列的数据都取出来。

- 将两个表里面取出的数据合并,使用交叉联结的方式合并。

- 将一个表中的所有行与另个表中所有合并在一起。

左联结

左联结是将左侧表作为主表,并指定主表的某一列为【关联列】。运行时,主表的数据全部读出来;右边表的数据按照【关联列】进行选取,与【关联列】相同的数据会被选取,不同的数据不会被选取。选取之后,两个表的数据按照交叉联结的方式合并展示。

数据产品经理养成记(四):SQL多张表查询_第10张图片

举个例子,,现在有两张表,如下:一张学生信息表,一张学生成绩表,现在通过左联结将以下两张表合并后的结果会是怎样?

数据产品经理养成记(四):SQL多张表查询_第11张图片

先公布语句写法:

select a.学号,a.姓名,b.学号,b.课程,b.成绩

from学生信息表as a left join 学生成绩表as b

on a.学号 =b.学号;

可以发现语句和写法和inner join类似。通过以上语句,运行处的结果如下:

数据产品经理养成记(四):SQL多张表查询_第12张图片

因为学号0002在右边的表里没有对应的行,所以合并后,对应的位置显示空值。如果你想删除掉有空值的行,可以通过where字句增加一个筛选条件,如下:

selecta.学号,a.姓名,b.学号,b.课程,b.成绩f

rom学生信息表asaleftjoin学生成绩表asb

ona.学号 = b.学号

whereb.学号 =null;

右联结

右联结是将右侧表作为主表,并指定主表的某一列为【关联列】。运行时,主表的数据全部读出来;左边表的数据按照【关联列】进行选取,与【关联列】相同的数据会被选取,不同的数据不会被选取。选取之后,两个表的数据按照交叉联结的方式合并展示。

具体的写法与左联结类似,我这里就不再举例了,大家可以自己打开Navicat写一写。

全联结

数据产品经理养成记(四):SQL多张表查询_第13张图片

全联结会返回两个表的所有行。当A表【关联列】的值与B表【关联列】的值相等时,按照交叉联结合并显示。

当A表【关联列】的值与B表【关联列】的值不相等时,另一个表中对应地方的值用控制来填充。(类似左联结和右联结的结合)

举个例子:

数据产品经理养成记(四):SQL多张表查询_第14张图片

全联结后显示的结果为:

数据产品经理养成记(四):SQL多张表查询_第15张图片

说明:MYSQL是不支持全联结的。一般来说,全联结应用场景也不多。

3. 案例解答

回到文章一开始的问题:

数据产品经理养成记(四):SQL多张表查询_第16张图片

假设你在做一款贷款产品,这里有两张表:用户表(userinfo)、借款还款表(loanapp)。你想查询所有用户的借款总笔数、借款总金额,就需要以用户作为关联条件,从三张表里面查找相应的数据进行分析。具体如何实现?

说明:遇到问题的时候,一定不能上来就写SQL语句,这里有一个三步走分析模型,分享给大家:

1. 拆解问题—2. 写出分析思路—3. 写出对应的SQL字句

1. 拆解问题

以上问题拆分成三个关键部分:所有用户,借款总笔数,借款总金额

2. 分析思路

所有用户:用户ID,用户姓名,在userinfo查询

借款总笔数:按照用户ID分组,对借款编号按照笔数计数(count)

借款总金额:按照用户ID分组,对借款金额求和(sum)

3. 写出SQL语句

selecta.ID,a.姓名,b.ID,count(借款编号)as借款总笔数,sum(借款金额)as借款总金额fromuserinfoasaleftjoinloanappasbona.ID = B.ID

groupbya.ID;

到此为止,简单查询和多表查询告一段落。在以后的文章中,我会尽量举一些工作中的实例,由浅入深,与大家一起深入掌握这门语言。接下来将分享复杂查询,和一些实战数据分析。如果有写的不对的地方,欢迎指正。也希望你持续关注,公号:数据产品经理之路。

你可能感兴趣的:(数据产品经理养成记(四):SQL多张表查询)