SQL语句中JOIN的用法场景分析


Posted in SQL Server onJuly 25, 2021

记录:256

写SQL最高境界:SELECT * FROM 表名。当然这是一句自嘲。探究一下SQL语句中JOIN的用法,直到经历这个场景,变得想验证一下究竟。

一、场景

把关系型数据库A中表TEST_TB01和TEST_TB02迁移到大数据平台M(MaxCompute大数据平台)。TEST_TB01单表1000万条记录,TEST_TB02单表80万条记录。

在关系型数据库中,TEST_TB01和TEST_TB02中有主键约束。在产生新增业务数据时,不会存在重复数据插入。但是,当数据迁移到大数据平台后,由于在大数据平台中无主键约束功能。在产生新增业务数据时,TEST_TB01和TEST_TB02均均插入了重复数据。

在一个计算任务中,TEST_TB01和TEST_TB02根据某个字段JOIN连接,计算出了一份结果数据,数据推送到使用方的关系型数据库C。直接导致了C数据库的对应表的表空间撑爆,监控预警。

原因:TEST_TB01和TEST_TB02有重复数据,使用JOIN连接后,生成了10亿+条数据,共计200G+数据,直接推送到C数据库。

那次考虑不周,瞬间懵了,感觉SQL语句中的JOIN变得陌生极了。于是想探究一下以作记录。

二、建表

TEST_TB01建表语句:

create table TEST_TB01
(
  sensor_id   BIGINT,
  part_id     BIGINT
 )
COMMENT '数据表一';

TEST_TB02建表语句:

create table TEST_TB02
(
  part_id    BIGINT,
  elem_id    BIGINT
 )
 COMMENT '数据表二';

三、SQL语句中使用JOIN无重复数据情况

在SQL语句中使用JOIN无重复数据情况,即在TEST_TB01和TEST_TB02表中均无重复数据情况。分别使用JOIN、INNER JOIN、LEFT JOIN、LEFT OUTER JOIN、RIGHT JOIN、FULL JOIN验证。

在TEST_TB01插入数据:

insert into TEST_TB01 (sensor_id,part_id) values(2101,9911);
insert into TEST_TB01 (sensor_id,part_id) values(2102,9912);
insert into TEST_TB01 (sensor_id,part_id) values(2103,9913);
insert into TEST_TB01 (sensor_id,part_id) values(2104,9914);
insert into TEST_TB01 (sensor_id,part_id) values(2105,9915);

在TEST_TB02插入数据:

insert into TEST_TB02 (part_id,elem_id) values(9911,8901);
insert into TEST_TB02 (part_id,elem_id) values(9912,8902);
insert into TEST_TB02 (part_id,elem_id) values(9913,8903);
insert into TEST_TB02 (part_id,elem_id) values(9916,8906);

查看TEST_TB01数据:

SQL语句中JOIN的用法场景分析

查看TEST_TB02数据:

SQL语句中JOIN的用法场景分析

1.在SQL中使用JOIN

TEST_TB01和TEST_TB02根据part_id使用JOIN连接,只返回两个表(TEST_TB01和TEST_TB02)中连接字段相等的记录。

SQL语句:

SELECT
  *
FROM
  TEST_TB01 aa
JOIN TEST_TB02 bb
    ON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;

执行结果:

SQL语句中JOIN的用法场景分析

2.在SQL中使用INNER JOIN

TEST_TB01和TEST_TB02根据part_id使用INNER JOIN连接,只返回两个表(TEST_TB01和TEST_TB02)中连接字段相等的记录。INNER JOIN和JOIN效果等价。

SQL语句:

SELECT
  *
FROM
  TEST_TB01 aa
INNER JOIN TEST_TB02 bb
    ON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;

执行结果:

SQL语句中JOIN的用法场景分析

3.在SQL中使用LEFT JOIN

TEST_TB01和TEST_TB02根据part_id使用LEFT JOIN连接,左连接,返回左表(TEST_TB01)中所有的记录以及右表(TEST_TB02)中连接字段相等的记录。

SQL语句:

SELECT
  *
FROM
  TEST_TB01 aa
LEFT JOIN TEST_TB02 bb
    ON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;

执行结果:

SQL语句中JOIN的用法场景分析

4.在SQL中使用LEFT OUTER JOIN

TEST_TB01和TEST_TB02根据part_id使用LEFT OUTER JOIN连接,左外连接,返回左表(TEST_TB01)中所有的记录以及右表(TEST_TB02)中连接字段相等的记录。LEFT OUTER JOIN

和LEFT JOIN等价。

SQL语句:

SELECT
  *
FROM
  TEST_TB01 aa
LEFT OUTER JOIN TEST_TB02 bb
    ON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;

执行结果:

SQL语句中JOIN的用法场景分析

5.在SQL中使用RIGHT JOIN

TEST_TB01和TEST_TB02根据part_id使用RIGHT JOIN连接,右连接,返回右表(TEST_TB02)中所有的记录以及左表(TEST_TB01)中连接字段相等的记录

SQL语句:

SELECT
  *
FROM
  TEST_TB01 aa
RIGHT JOIN TEST_TB02 bb
    ON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;

执行结果:

SQL语句中JOIN的用法场景分析

6.在SQL中使用FULL JOIN

TEST_TB01和TEST_TB02根据part_id使用FULL JOIN连接,外连接,返回两个表中的行:LEFT JOIN + RIGHT JOIN所有行记录。

SQL语句:

SELECT
  *
FROM
  TEST_TB01 aa
FULL JOIN TEST_TB02 bb
    ON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;

执行结果:

SQL语句中JOIN的用法场景分析

四、SQL语句中使用JOIN有重复数据情况

在SQL语句中使用JOIN有重复数据情况,即在TEST_TB01和TEST_TB02表中均有重复数据情况。分别使用JOIN、INNER JOIN、LEFT JOIN、LEFT OUTER JOIN、RIGHT JOIN、FULL JOIN验证。

在TEST_TB01插入数据:

insert into TEST_TB01 (sensor_id,part_id) values(2101,9911);
insert into TEST_TB01 (sensor_id,part_id) values(2102,9912);
insert into TEST_TB01 (sensor_id,part_id) values(2103,9913);
insert into TEST_TB01 (sensor_id,part_id) values(2104,9914);
insert into TEST_TB01 (sensor_id,part_id) values(2105,9915);
--造重复数据
insert into TEST_TB01 (sensor_id,part_id) values(2102,9912);
insert into TEST_TB01 (sensor_id,part_id) values(2103,9913);

在TEST_TB02插入数据:

insert into TEST_TB02 (part_id,elem_id) values(9911,8901);
insert into TEST_TB02 (part_id,elem_id) values(9912,8902);
insert into TEST_TB02 (part_id,elem_id) values(9913,8903);
insert into TEST_TB02 (part_id,elem_id) values(9916,8906);
--造重复数据
insert into TEST_TB02 (part_id,elem_id) values(9912,8902);
insert into TEST_TB02 (part_id,elem_id) values(9913,8903);

查看TEST_TB01数据:

SQL语句中JOIN的用法场景分析

查看TEST_TB02数据:

SQL语句中JOIN的用法场景分析

1.在SQL中使用JOIN

TEST_TB01和TEST_TB02根据part_id使用JOIN连接,只返回两个表(TEST_TB01和TEST_TB02)中连接字段相等的记录。

SQL语句:

SELECT
  *
FROM
  TEST_TB01 aa
JOIN TEST_TB02 bb
    ON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;

执行结果:

SQL语句中JOIN的用法场景分析

2.在SQL中使用INNER JOIN

TEST_TB01和TEST_TB02根据part_id使用INNER JOIN连接,只返回两个表(TEST_TB01和TEST_TB02)中连接字段相等的记录。INNER JOIN和JOIN效果等价。

SQL语句:

SELECT
  *
FROM
  TEST_TB01 aa
INNER JOIN TEST_TB02 bb
    ON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;

执行结果:

SQL语句中JOIN的用法场景分析

3.在SQL中使用LEFT JOIN

TEST_TB01和TEST_TB02根据part_id使用LEFT JOIN连接,左连接,返回左表(TEST_TB01)中所有的记录以及右表(TEST_TB02)中连接字段相等的记录。

SQL语句:

SELECT
  *
FROM
  TEST_TB01 aa
LEFT JOIN TEST_TB02 bb
    ON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;

执行结果:

SQL语句中JOIN的用法场景分析

4.在SQL中使用LEFT OUTER JOIN

TEST_TB01和TEST_TB02根据part_id使用LEFT OUTER JOIN连接,左外连接,返回左表(TEST_TB01)中所有的记录以及右表(TEST_TB02)中连接字段相等的记录。LEFT OUTER JOIN

和LEFT JOIN等价。

SQL语句:

SELECT
  *
FROM
  TEST_TB01 aa
LEFT OUTER JOIN TEST_TB02 bb
    ON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;

执行结果:

SQL语句中JOIN的用法场景分析

5.在SQL中使用RIGHT JOIN

TEST_TB01和TEST_TB02根据part_id使用RIGHT JOIN连接,右连接,返回右表(TEST_TB02)中所有的记录以及左表(TEST_TB01)中连接字段相等的记录

SQL语句:

SELECT
  *
FROM
  TEST_TB01 aa
RIGHT JOIN TEST_TB02 bb
    ON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;

执行结果:

SQL语句中JOIN的用法场景分析

6.在SQL中使用FULL JOIN

TEST_TB01和TEST_TB02根据part_id使用FULL JOIN连接,外连接,返回两个表中的行:LEFT JOIN + RIGHT JOIN所有行记录。

SQL语句:

SELECT
  *
FROM
  TEST_TB01 aa
FULL JOIN TEST_TB02 bb
    ON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;

执行结果:

SQL语句中JOIN的用法场景分析

五、SQL中使用JOIN有重复与无重复数据区别

在SQL语句中使用JOIN有重复数据情况,使用JOIN连接,符合连接字段相等的记录的结果集是笛卡尔积,第一个表的行数乘以第二个表的行数。

六、解决方式

1.先去重再使用JOIN连接

根据业务规则先对TEST_TB01和TEST_TB02分别去重再使用JOIN连接。

2.先使用JOIN连接再去重

根据业务规则先对TEST_TB01和TEST_TB02使用JOIN连接生成结果集,再对结果集去重。

3.建议

在生产环境特别是数据量大场景,推荐使用第一种方式,先逐个表去重再使用JOIN连接。

七、关系型数据库验证表结构

本例是在DataWorks环境(即MaxCompute大数据平台)下验证,即在关系型数据库验证除表结构差异,其它均相同。

在ORACLE数据库建表语句:

create table TEST_TB01
(
  sensor_id  NUMBER(16),
  part_id  NUMBER(16)
 );
 
 create table TEST_TB02
(
  part_id  NUMBER(16),
  elem_id  NUMBER(16) 
 );

在MySQL数据库建表语句:

CREATE TABLE TEST_TB01
(
  sensor_id  BIGINT,
  part_id  BIGINT
 );
 
 CREATE TABLE TEST_TB02
(
  part_id  BIGINT,
  elem_id  BIGINT 
 );

以上,感谢。

到此这篇关于SQL语句中JOIN的用法的文章就介绍到这了,更多相关SQL JOIN的用法内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

SQL Server 相关文章推荐
2021-4-5课程——SQL Server查询【3】
Apr 05 SQL Server
SQLServer2008提示评估期已过解决方案
Apr 12 SQL Server
SQL Server作业失败:无法确定所有者是否有服务器访问权限的解决方法
Jun 30 SQL Server
Spark SQL 2.4.8 操作 Dataframe的两种方式
Oct 16 SQL Server
sql server 累计求和实现代码
Feb 28 SQL Server
使用SQL实现车流量的计算的示例代码
Feb 28 SQL Server
SQL Server内存机制浅探
Apr 06 SQL Server
sql server偶发出现死锁的解决方法
Apr 10 SQL Server
SQL Server数据库查询出现阻塞之性能调优
Apr 10 SQL Server
Sql Server 行数据的某列值想作为字段列显示的方法
Apr 20 SQL Server
SQL Server中T-SQL标识符介绍与无排序生成序号的方法
May 25 SQL Server
SQL Server2019安装的详细步骤实战记录(亲测可用)
Jun 10 SQL Server
sql通过日期判断年龄函数的示例代码
Jul 16 #SQL Server
利用 SQL Server 过滤索引提高查询语句的性能分析
SqlServer数据库远程连接案例教程
数据库之SQL技巧整理案例
Jul 07 #SQL Server
SQL Server中使用判断语句(IF ELSE/CASE WHEN )案例
Jul 07 #SQL Server
SQL Server代理:理解SQL代理错误日志处理方法
SQL Server作业失败:无法确定所有者是否有服务器访问权限的解决方法
You might like
php初学者写及时补给skype用户充话费的小程序
2008/11/02 PHP
php获取apk包信息的方法
2014/08/15 PHP
PHP常用技术文之文件操作和目录操作总结
2014/09/27 PHP
PHP限制HTML内容中图片必须是本站的方法
2015/06/16 PHP
微信支付开发维权通知实例
2016/07/12 PHP
PHP写的简单数字验证码实例
2017/05/23 PHP
Firefox getBoxObjectFor getBoundingClientRect联系
2008/10/26 Javascript
JavaScript 闭包在封装函数时的简单分析
2009/11/28 Javascript
玩转jQuery按钮 请告诉我你最喜欢哪些?
2012/01/08 Javascript
用nodejs写的一个简单项目打包工具
2013/05/11 NodeJs
Jquery 数组操作大全个人总结
2013/11/13 Javascript
jQuery实现的Div窗口震动特效
2014/06/09 Javascript
js防止DIV布局滚动时闪动的解决方法
2014/10/30 Javascript
让JavaScript中setTimeout支持链式操作的方法
2015/06/19 Javascript
js实现拖拽效果(构造函数)
2015/12/14 Javascript
javascript类型系统 Window对象学习笔记
2016/01/07 Javascript
使用jQuery的toggle()方法对HTML标签进行显示、隐藏的方法(示例)
2016/09/01 Javascript
微信小程序中页面FOR循环和嵌套循环
2017/06/21 Javascript
基于vue.js中关于下拉框的值默认及绑定问题
2018/08/22 Javascript
浅谈angularJs函数的使用方法(大小写转换,拷贝,扩充对象)
2018/10/08 Javascript
vue使用v-if v-show页面闪烁,div闪现的解决方法
2018/10/12 Javascript
跟老齐学Python之编写类之二方法
2014/10/11 Python
python检测文件夹变化,并拷贝有更新的文件到对应目录的方法
2018/10/17 Python
Python+selenium点击网页上指定坐标的实例
2019/07/05 Python
python爬取股票最新数据并用excel绘制树状图的示例
2021/03/01 Python
HTML5对手机页面长按会粘贴复制禁用的解决方法
2016/07/19 HTML / CSS
详解HTML5新增标签
2017/11/27 HTML / CSS
html5定制表单_动力节点Java学院整理
2017/07/11 HTML / CSS
德国净水壶和滤芯品牌:波尔德PearlCo(家用净水器)
2020/04/29 全球购物
10条PHP编程习惯
2014/05/26 面试题
八皇后问题,输出了所有情况,不过有些结果只是旋转了90度
2016/08/15 面试题
广播电视新闻学专业应届生求职信
2013/10/08 职场文书
新三好学生主要事迹
2014/01/23 职场文书
职称评定自我鉴定
2014/03/18 职场文书
小学英语教师研修感悟
2015/11/18 职场文书
廉政党课工作报告案例
2019/06/21 职场文书