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 相关文章推荐
SQLServer2008提示评估期已过解决方案
Apr 12 SQL Server
SQL Server中交叉联接的用法详解
Apr 22 SQL Server
SQL 窗口函数实现高效分页查询的案例分析
May 21 SQL Server
sql中mod()函数取余数的用法
May 29 SQL Server
SQLServer 错误: 15404,无法获取有关 Windows NT 组/用户 WIN-8IVSNAQS8T7\Administrator 的信息
Jun 30 SQL Server
SQL SERVER存储过程用法详解
Feb 24 SQL Server
SQL Server查询某个字段在哪些表中存在
Mar 03 SQL Server
SQL Server数据库查询出现阻塞之性能调优
Apr 10 SQL Server
如何使用SQL Server语句创建表
Apr 12 SQL Server
SQL使用复合索引实现数据库查询的优化
May 25 SQL Server
在SQL Server中使用 Try Catch 处理异常的示例详解
Jul 15 SQL Server
SqlServer常用函数及时间处理小结
May 08 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 header功能的使用
2013/10/28 PHP
从数据库读取数据后将其输出成html标签的三种方法
2014/10/13 Javascript
jQuery对于显示和隐藏等常用状态的判断方法
2014/12/13 Javascript
详细解读AngularJS中的表单验证编程
2015/06/19 Javascript
探究Javascript模板引擎mustache.js使用方法
2016/01/26 Javascript
JavaScript随机打乱数组顺序之随机洗牌算法
2016/08/02 Javascript
用js控件div的滚动条,让它在内容更新时自动滚到底部的实现方法
2016/10/27 Javascript
JScript实现表格的简单操作
2017/08/15 Javascript
微信小程序实现传参数的几种方法示例
2018/01/10 Javascript
vue如何通过id从列表页跳转到对应的详情页
2018/05/01 Javascript
Vue axios设置访问基础路径方法
2018/09/19 Javascript
Vuejs学习笔记之使用指令v-model完成表单的数据双向绑定
2019/04/29 Javascript
Angular 多模块项目构建过程
2020/02/13 Javascript
解决VantUI popup 弹窗不弹出或无蒙层的问题
2020/11/03 Javascript
python 实现插入排序算法
2012/06/05 Python
Python fileinput模块使用实例
2015/05/28 Python
python中正则的使用指南
2016/12/04 Python
详解Python中 sys.argv[]的用法简明解释
2017/12/20 Python
PyQt5实现拖放功能
2018/04/25 Python
Python图像滤波处理操作示例【基于ImageFilter类】
2019/01/03 Python
Python理解递归的方法总结
2019/01/28 Python
python安装virtualenv虚拟环境步骤图文详解
2019/09/18 Python
Python FTP文件定时自动下载实现过程解析
2019/11/12 Python
python爬虫开发之PyQuery模块详细使用方法与实例全解
2020/03/09 Python
python写文件时覆盖原来的实例方法
2020/07/22 Python
python实现图片,视频人脸识别(opencv版)
2020/11/18 Python
浅谈HTML5 服务器推送事件(Server-sent Events)
2017/08/01 HTML / CSS
移动端html5判断是否滚动到底部并且下拉加载
2019/11/19 HTML / CSS
潘多拉珠宝俄罗斯官方网上商店:PANDORA俄罗斯
2020/09/22 全球购物
幼儿园教师岗位职责
2014/03/17 职场文书
五年级学生评语
2014/04/22 职场文书
单位个人查摆问题及整改措施
2014/10/28 职场文书
初一年级组工作总结
2015/08/12 职场文书
初一英语教学反思
2016/02/15 职场文书
找规律教学反思
2016/02/23 职场文书
Android使用EventBus发送消息,Fragment中接收消息的方法会执行多次
2022/04/24 Java/Android