Mysql多表合并以及连接问题


目的

1.为了备战过两天的面试,我又重新给孙老师的课件看了一遍,学累了,就写写自己的新的体会,和遇到的问题,来进行一个记录,这是知识产出的过程,据说可以帮助我学习,看视频什么的都是被动学习,不进行及时总结,可能两天就忘了。根据艾宾什么斯遗忘曲线,学完了30天不看就约等于没学(由此可见我上次写的20理综选择题错很多不是偶然。。),所以这次我要在老师的基础上进行知识点的总结,不是上次的生搬硬套。

想法

2.经过上午近三个小时的敲sql语句,我好像突然懂了!注意格式,不能着急,循序渐进就可以。我开始学习就是很慌张,自以为原来学过,大致看一遍就差不多,其实这样是很危险的想法,虽然勉强算是个科班出身的,但是大部分上课都是摸鱼摸过来的(听说清华大学开了摸鱼课,有机会一定去听几节课,咳咳,当然不是为了摸鱼,大大说过全国广大青少年,要志存高远,增长知识,锤炼意志,让青春在时代进步中焕发出绚丽的光彩。”对啊正直青春的我一定会秉承这种信念,在我的岗位上发光发热的!!),考试也是使用毕生最高的效率,记得有一次oracle大作业我直接抗到了夜里3点(在这里小小的说明一下,证明自己也是有决心的!),虽然最后得分不是很好,但是勉强通过了。大学的时候我们大一开设的是关系型数据库这一门课,书本是我们老师自己编的,也算是对好多名词有了了解,上机课就是mysql,sql语句敲得咋样不说,我这mysql可是没少安装卸载,最起码也是个安装小能手,哈哈。结合自身案例,现在你们要对自己有个清醒的认识,会不会只有自己知道!下面我来介绍一下我的方法,比较笨,毕竟咱的学习能力,还在学习当中,learnning  to learn。

实施

首先,由于时间可能不是很充分,我就找了B站,孙兴华老师的视频,强烈安利大家看看,主要针对新手,教大家如何进行使用数据库,老师的课件也是免费分享,下面就有链接,很是良心。安装也是“傻瓜式”的安装方法,所有步骤的图片都有!这个我们上学时候的大作业是一模一样的,软件安装,截图,写出遇到的问题。

里面着重讲的是基础的增删改查,就是教大家如何使用数据库进行数据查询,根据二八定律,我们学会80%,太难的20%是我们日常用不到的,先对日常使用的部分来进行学习,入门后,在工作中遇到别的问题,我们在百度,或者询问别人。对于多表合并和多表进行的连接查询不是很懂。我就详细的说一下我的理解吧,大家在日常使用中,发现有不对的,也欢迎指正,大家一起进步,一起拿高薪!!

多表合并问题

1.多表合并数据使用union

(偷懒了直接截的图。。结果图我会自己跑出来的。)

1.将两张表合并不去重

SELECT * FROM `1班` UNION ALL SELECT * FROM `2班`;

很简单对吧直接两个select语句中间连接一下就好了

注意:

有重复值,这里面得重复值指的是例如杨过语文数学英语成绩相同的就有4个,若有任一一条信息不一样,数学成绩100的话就不算是重复的值了

2.将两张表合并去重

SELECT * FROM `1班` UNION SELECT * FROM `2班`;

重复的杨过就被干掉了!

总结:

UNION ALL 不去重

UNION 去重

注意:

1、不管是UNION还是UNION ALL,都要求SELECT语句拥有相同的列数,而且字段的排放顺序必须相同

2、如果两张原始表的顺序不一致,你需要手动在SELECT后面写字段强行把他顺序变成一致。 例如: SELECT 姓名,语文 FROM `1班` UNION ALL SELECT 姓名,语文 FROM `2班`;

3、列的名字或别名,是由第一个Select语句的选择列表决定的。

4、ORDER BY子句,必需放在最后一个Select后面

5、如果你遇到了列不一致的情况,如何处理?

SELECT 姓名,语文,数学,英语 FROM `1班` UNION ALL SELECT 姓名,语文,NULL,英语 FROM `2班`

SELECT 姓名,语文,数学,英语 FROM `1班` UNION ALL SELECT 姓名,语文,'未考',英语 FROM `2班`

自己手动将字段的内容设置进去

多个表合并

SELECT * FROM `1班`

UNION ALL

SELECT * FROM `2班`

UNION ALL

SELECT * FROM `3班`

UNION ALL

………..

(可以无限进行连接,最好使用上述的排列方法,可以让你的界面显得美观)

注意:

被union 或 union all 连接的sql 子句,单个子句中不用写order by ,因为不会有排序的效果。但可以对最终的结果集进行排序

(select 字段名 from 表1 order by 字段名) union all (select 字段名 from 表2 order by 字段名); //没有排序效果

(select 字段名 from 表1) union all (select 字段名 from 表2) order by 字段名; //有排序效果

连接查询

 

 (图是偷来的,但爱你们是真的!)

 这个图片就很好的解释了啥叫连接查询,两个表有相同的字段名,就可以进行连接,这样方便我们找到完整的信息。

 1多表配合使用

例1..将店铺表中的表名Vlookup到销售名中

分析: 首先我先截图看看这两个表,找找相同的字段。这里使用的是店铺表和销售表。

销售表:                                                                                    店铺表:

                           

 我们可以很清楚的看到两张表都有相同的店号这一栏。所以我们可以根据这个来进行多表达连接:

 方法一

SELECT `销售表`.`店号`,`店铺表`.`店名`,`销售表`.`商品编码`,`销售表`.`销售数量`

FROM `销售表`,`店铺表`

WHERE `店铺表`.`店号`=`销售表`.`店号`;

 这样一看,全是汉字,虽说易于理解,但是我们在实际应用中不会这样来进行查询的

 以上语句中,店铺表和销售表两个表名反复出现,使代码书写和阅读都趋于复杂,此时我们可以使用表的别名进行简化。

SELECT a.`店号`,b.`店名`,a.`商品编码`,a.`销售数量`

FROM `销售表`a,`店铺表`b

WHERE b.`店号`=a.`店号`;

也可以写成:【推荐写法】

SELECT a.店号,店名,商品编码,销售数量

FROM `销售表`a,`店铺表`b

WHERE b.`店号`=a.`店号`;

这里我就上述代码写出来自己的理解:

首先第一行写的是我们主题的显示内容字段的表格,相同的店号内容我们使用别名a.来代表,这样我们可以减少重复的内容,减少工作量

可以看结果,结果的字段名和第一行是一样的:

第二行无非就是写出了需要连接的两个表格,顺便给他们起了一个别名,

第三行就是连接的条件了,这里面就是店号相同,我们需要把显示的表写在后面(这里我也是只会使用,课程上讲了,忘了,所以说复习是很必要的啊!!)这样写不会错的,

 一目了然,结果如下:

 三种结果都一样,这里就不进行过多的介绍了。

注意:

 对比上一条的语句,不难发现部分字段名省略了表名,这是因为相关字段名称在连接表中是独一无二的;

而‘店号’是店铺表和销售表都存在 的字段名,则必须提供表名,否则系统无法识别字段来源。

 凡是表里没有这个字段的时候(你自造的字段)必需用HAVING,不能使用WHERE

凡是字段名在FROM表中是唯一的,字段名前可以省略表名

内部连接  FROM+WHERE 1992年

在语句形式上,连接查询通常有两种实现方式。一种是FROM子句列出所有需要连接的表,然后通过WHERE子句列出筛选条件;

另一种是通过关键字JOIN建立 表和表之间的连接,再通过关键字ON指定连接条件。

语法:

SELECT 字段名 FROM 表1,表2 WHERE 表1.字段名=表2.字段名 FROM子句列出需要连接查询的多个表,不同表名之间使用英文逗号间隔,

然后WHERE子句指定了筛选的条件,最后SELECT子句指定需要提取字段的名称。

 

 例:将店铺名称V到销售表中

交叉连接和内部连接:需要注意,无论你左表还是右表,只有都相匹配才能结果才能显示。

内部连接  INNER JOIN+ON 1999年

内连接通过关键字INNER JOIN 将多表连接,并通过关键字ON,指定连接条件。内连接又称等同连接,返回连接表所有相匹配的记录,舍弃不匹配的记录。

 

内部联接分类:

等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列。

select * from 表1 inner join 表2 on 表1.字段名 = 表2.字段名

不等值连接:在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些运算符包括>、>=、<=、<、!>、!<和<>。

概念:在连接条件中使用除等于号之外运算符(>、<、<>、>=、<=、!>和!<)

select * from 表1 inner join 表2 on 表1.字段名 <> 表2.字段名

自然连接:在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列。

一、等值连接

语法:

select 字段名 from 表1 inner join 表2 on 连接条件

 例 1:把店名V过来 

 SELECT 日期,a.店号,店名,商品编码,销售数量

FROM 销售表 a

INNER JOIN 店铺表 b

ON a.`店号`=b.`店号`

 

 例2:查询店号为1.3.7的店名,销售总数量

SELECT a.店号,店名,SUM(销售数量) AS 销售总量

FROM 销售表 a

INNER JOIN 店铺表 b

ON a.`店号`=b.`店号`

WHERE a.店号 in(1,3,7)

GROUP BY 店名 # 这里使用a.店号效果一样

例3.将店铺表中的表名Vlookup到销售名中,条件是2020.1.1至1.3

------------恢复内容开始------------

目的

1.为了备战过两天的面试,我又从新给孙老师的课件看了一遍,学累了,就写写自己的新的体会,和遇到的问题,来进行一个记录,这是知识产出的过程,据说可以帮助我学习,看视频什么的都是被动学习,不进行及时总结,可能两天就忘了。根据艾宾什么斯遗忘曲线,学完了30天不看就约等于没学(由此可见我上次写的20理综选择题错很多不是偶然。。),所以这次我要在老师的基础上进行知识点的总结,不是上次的生搬硬套。

想法

2.经过上午近三个小时的敲sql语句,我好像突然懂了!注意格式,不能着急,循序渐进就可以。我开始学习就是很慌张,自以为原来学过,大致看一遍就差不多,其实这样是很危险的想法,虽然勉强算是个科班出身的,但是大部分上课都是摸鱼摸过来的(听说清华大学开了摸鱼课,有机会一定去听几节课,咳咳,当然不是为了摸鱼,大大说过全国广大青少年,要志存高远,增长知识,锤炼意志,让青春在时代进步中焕发出绚丽的光彩。”对啊正直青春的我一定会秉承这种信念,在我的岗位上发光发热的!!),考试也是使用毕生最高的效率,记得有一次oracle大作业我直接抗到了夜里3点(在这里小小的说明一下,证明自己也是有决心的!),虽然最后得分不是很好,但是勉强通过了。大学的时候我们大一开设的是关系型数据库这一门课,书本是我们老师自己编的,也算是对好多名词有了了解,上机课就是mysql,sql语句敲得咋样不说,我这mysql可是没少安装卸载,最起码也是个安装小能手,哈哈。结合自身案例,现在你们要对自己有个清醒的认识,会不会只有自己知道!下面我来介绍一下我的方法,比较笨,毕竟咱的学习能力,还在学习当中,learnning  to learn。

实施

首先,由于时间可能不是很充分,我就找了B站,孙兴华老师的视频,强烈安利大家看看,主要针对新手,教大家如何进行使用数据库,老师的课件也是免费分享,下面就有链接,很是良心。安装也是“傻瓜式”的安装方法,所有步骤的图片都有!这个我们上学时候的大作业是一模一样的,软件安装,截图,写出遇到的问题。

里面着重讲的是基础的增删改查,就是教大家如何使用数据库进行数据查询,根据二八定律,我们学会80%,太难的20%是我们日常用不到的,先对日常使用的部分来进行学习,入门后,在工作中遇到别的问题,我们在百度,或者询问别人。对于多表合并和多表进行的连接查询不是很懂。我就详细的说一下我的理解吧,大家在日常使用中,发现有不对的,也欢迎指正,大家一起进步,一起拿高薪!!

多表合并问题

1.多表合并数据使用union

(偷懒了直接截的图。。结果图我会自己跑出来的。)

1.将两张表合并不去重

SELECT * FROM `1班` UNION ALL SELECT * FROM `2班`;

很简单对吧直接两个select语句中间连接一下就好了

注意:

有重复值,这里面得重复值指的是例如杨过语文数学英语成绩相同的就有4个,若有任一一条信息不一样,数学成绩100的话就不算是重复的值了

2.将两张表合并去重

SELECT * FROM `1班` UNION SELECT * FROM `2班`;

重复的杨过就被干掉了!

总结:

UNION ALL 不去重

UNION 去重

注意:

1、不管是UNION还是UNION ALL,都要求SELECT语句拥有相同的列数,而且字段的排放顺序必须相同

2、如果两张原始表的顺序不一致,你需要手动在SELECT后面写字段强行把他顺序变成一致。 例如: SELECT 姓名,语文 FROM `1班` UNION ALL SELECT 姓名,语文 FROM `2班`;

3、列的名字或别名,是由第一个Select语句的选择列表决定的。

4、ORDER BY子句,必需放在最后一个Select后面

5、如果你遇到了列不一致的情况,如何处理?

SELECT 姓名,语文,数学,英语 FROM `1班` UNION ALL SELECT 姓名,语文,NULL,英语 FROM `2班`

SELECT 姓名,语文,数学,英语 FROM `1班` UNION ALL SELECT 姓名,语文,'未考',英语 FROM `2班`

自己手动将字段的内容设置进去

多个表合并

SELECT * FROM `1班`

UNION ALL

SELECT * FROM `2班`

UNION ALL

SELECT * FROM `3班`

UNION ALL

………..

(可以无限进行连接,最好使用上述的排列方法,可以让你的界面显得美观)

注意:

被union 或 union all 连接的sql 子句,单个子句中不用写order by ,因为不会有排序的效果。但可以对最终的结果集进行排序

(select 字段名 from 表1 order by 字段名) union all (select 字段名 from 表2 order by 字段名); //没有排序效果

(select 字段名 from 表1) union all (select 字段名 from 表2) order by 字段名; //有排序效果

连接查询

 

 (图是偷来的,但爱你们是真的!)

 这个图片就很好的解释了啥叫连接查询,两个表有相同的字段名,就可以进行连接,这样方便我们找到完整的信息。

 1多表配合使用

例1..将店铺表中的表名Vlookup到销售名中

分析: 首先我先截图看看这两个表,找找相同的字段。这里使用的是店铺表和销售表。

销售表:                                                                                    店铺表:

                           

 我们可以很清楚的看到两张表都有相同的店号这一栏。所以我们可以根据这个来进行多表达连接:

 方法一

SELECT `销售表`.`店号`,`店铺表`.`店名`,`销售表`.`商品编码`,`销售表`.`销售数量`

FROM `销售表`,`店铺表`

WHERE `店铺表`.`店号`=`销售表`.`店号`;

 这样一看,全是汉字,虽说易于理解,但是我们在实际应用中不会这样来进行查询的

 以上语句中,店铺表和销售表两个表名反复出现,使代码书写和阅读都趋于复杂,此时我们可以使用表的别名进行简化。

SELECT a.`店号`,b.`店名`,a.`商品编码`,a.`销售数量`

FROM `销售表`a,`店铺表`b

WHERE b.`店号`=a.`店号`;

也可以写成:【推荐写法】

SELECT a.店号,店名,商品编码,销售数量

FROM `销售表`a,`店铺表`b

WHERE b.`店号`=a.`店号`;

这里我就上述代码写出来自己的理解:

首先第一行写的是我们主题的显示内容字段的表格,相同的店号内容我们使用别名a.来代表,这样我们可以减少重复的内容,减少工作量

可以看结果,结果的字段名和第一行是一样的:

第二行无非就是写出了需要连接的两个表格,顺便给他们起了一个别名,

第三行就是连接的条件了,这里面就是店号相同,我们需要把显示的表写在后面(这里我也是只会使用,课程上讲了,忘了,所以说复习是很必要的啊!!)这样写不会错的,

 一目了然,结果如下:

 三种结果都一样,这里就不进行过多的介绍了。

注意:

 对比上一条的语句,不难发现部分字段名省略了表名,这是因为相关字段名称在连接表中是独一无二的;

而‘店号’是店铺表和销售表都存在 的字段名,则必须提供表名,否则系统无法识别字段来源。

 凡是表里没有这个字段的时候(你自造的字段)必需用HAVING,不能使用WHERE

凡是字段名在FROM表中是唯一的,字段名前可以省略表名

内部连接  FROM+WHERE 1992年

在语句形式上,连接查询通常有两种实现方式。一种是FROM子句列出所有需要连接的表,然后通过WHERE子句列出筛选条件;

另一种是通过关键字JOIN建立 表和表之间的连接,再通过关键字ON指定连接条件。

语法:

SELECT 字段名 FROM 表1,表2 WHERE 表1.字段名=表2.字段名 FROM子句列出需要连接查询的多个表,不同表名之间使用英文逗号间隔,

然后WHERE子句指定了筛选的条件,最后SELECT子句指定需要提取字段的名称。

 

 例:将店铺名称V到销售表中

交叉连接和内部连接:需要注意,无论你左表还是右表,只有都相匹配才能结果才能显示。

内部连接  INNER JOIN+ON 1999年

内连接通过关键字INNER JOIN 将多表连接,并通过关键字ON,指定连接条件。内连接又称等同连接,返回连接表所有相匹配的记录,舍弃不匹配的记录。

 

内部联接分类:

等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列。

select * from 表1 inner join 表2 on 表1.字段名 = 表2.字段名

不等值连接:在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些运算符包括>、>=、<=、<、!>、!<和<>。

概念:在连接条件中使用除等于号之外运算符(>、<、<>、>=、<=、!>和!<)

select * from 表1 inner join 表2 on 表1.字段名 <> 表2.字段名

自然连接:在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列。

一、等值连接

语法:

select 字段名 from 表1 inner join 表2 on 连接条件

 例 1:把店名V过来 

 SELECT 日期,a.店号,店名,商品编码,销售数量

FROM 销售表 a

INNER JOIN 店铺表 b

ON a.`店号`=b.`店号`

 

 例2:查询店号为1.3.7的店名,销售总数量

SELECT a.店号,店名,SUM(销售数量) AS 销售总量

FROM 销售表 a

INNER JOIN 店铺表 b

ON a.`店号`=b.`店号`

WHERE a.店号 in(1,3,7)

GROUP BY 店名 # 这里使用a.店号效果一样

例3.将店铺表中的表名Vlookup到销售名中,条件是2020.1.1至1.3

SELECT 日期,a.店号,店名,商品编码,销售数量

FROM 销售表 a

INNER JOIN 店铺表 b

ON b.店号=a.店号

WHERE 日期 BETWEEN '2020-01-01' AND '2020-01-03';

 

注意:

如果假设有一个店号,在商品表里有,销售表里没有,那么就V不过来,反之,在销售表里有,在商品表里没有,也V不过来,因为取的是同时符合条件 的。条件是什么呀?是:

b.`店号` = a.`店号`

如果你想成为数据库开发和维护人员注意:a表和b表的店号类型要一致。

分析结果: 1、运算FROM语句将两个表连接在一起,连接条件是两个表店号相等的内容才会连接

2、WHETE条件只保留级别日期是2020.1.1至1.3区间的数据

3、SELECT后面是返回的字段名

例4:在例1基础上,再添加条件,只看店铺1.3.7这三家店,商品只看A001和B005这两种商品的销售情况

SELECT 日期,a.店号,店名,商品编码,销售数量

FROM 销售表 a

INNER JOIN 店铺表 b

ON b.店号=a.店号

WHERE 日期 BETWEEN '2020-01-01' and '2020-01-03' and 商品编码 in('A001','B005') and a.店号 in(1,3,7)

这道题的核心可能就是where后面的语句,其实你看下答案,也不是很难理解,可能就是因为对这些细节上的东西,把我的不是很深。

内部连接之自然连接

这不是重点,了解即可,你有可能用不到这些知识 网上有些教程和书籍上讲的不对,他们讲的自连接还是普通的内连接,比如用商品名称去找他的大类,那不还是V过来吗?

自连接: 自己的表和自己的表连接:一张表拆为两张一样的表

 

SELECT a.名字 AS 著作,b.名字 AS 人物
FROM 自然连接 a,自然连接 b
WHERE a.子分类 = b.父分类

 左外连接 LEFT JOIN + ON 【推荐】

 左连接,返回左表中的所有行,如果左表中行在右表中没有匹配行,则结果中右表中的列返回空值。

 例:我想将销售表按商品编码,将商品里的其它信息都V过来

SELECT a.*,商品名称,大类编码,大类名,小类编码,小类名,进价,售价

FROM `销售表`a

LEFT JOIN `商品表`b

ON a.商品编码 = b.商品编码

如果您想把列的顺序排好:

SELECT 日期,店号,a.`商品编码`,商品名称,大类编码,大类名,小类编码,小类名,进价,售价,销售数量

FROM `销售表`a

LEFT JOIN `商品表`b

ON a.商品编码 = b.商品编码

如果您想计算销售金额

SELECT 日期,店号,a.`商品编码`,商品名称,大类编码,大类名,小类编码,小类名,进价,售价,销售数量,销售数量*售价 AS 销售金额

FROM `销售表`a

LEFT JOIN `商品表`b

ON a.商品编码 = b.商品编码

根据以上基础,我想设置日期为 2020-01-01 至 2020-01-03 SELECT 日期,店号,a.`商品编码`,商品名称,大类编码,大类名,小类编码,小类名,进价,售价,销售数量,销售数量*售价 AS 销售金额 5.1.4 左外连接 LEFT JOIN + ON 【推荐】

SELECT 日期,店号,a.`商品编码`,商品名称,大类编码,大类名,小类编码,小类名,进价,售价,销售数量,销售数量*售价 AS 销售金额

FROM `销售表`a LEFT JOIN `商品表`b

ON a.商品编码 = b.商品编码

WHERE 日期 BETWEEN '2020-01-01' AND '2020-01-03'

根据以上基础,我想看每家店铺这一时间段内的 销售金额

SELECT 日期,店号,a.`商品编码`,商品名称,大类编码,大类名,小类编码,小类名,进价,售价,销售数量,销售数量*售价 AS 销售金额,(销售数量*售价)-(销售数量*进价) AS 毛利额

FROM `销售表`a LEFT JOIN `商品表`b ON a.商品编码 = b.商品编码

WHERE 日期 BETWEEN '2020-01-01' AND '2020-01-03'

GROUP BY 店号

ORDER BY 销售金额 DESC;

就先到这里吧,一上午也就看了这么多。

再次感谢孙老师的课件   !!