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-3课程——SQL Server查询【2】
Apr 05 SQL Server
SqlServer 垂直分表(减少程序改动)
Apr 16 SQL Server
SQL Server2019数据库之简单子查询的具有方法
Apr 27 SQL Server
数据库之SQL技巧整理案例
Jul 07 SQL Server
利用 SQL Server 过滤索引提高查询语句的性能分析
Jul 15 SQL Server
SQLServer之常用函数总结详解
Aug 30 SQL Server
Sql Server之数据类型详解
Feb 28 SQL Server
使用SQL实现车流量的计算的示例代码
Feb 28 SQL Server
SQL Server表分区降低运维和维护成本
Apr 08 SQL Server
SQL Server #{}可以防止SQL注入
May 11 SQL Server
SQL Server中锁的用法
May 20 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配置文件php.ini所在路径的二种方法
2014/05/26 PHP
PHP基于数组实现的分页函数实例
2014/08/20 PHP
php写app用的框架整理
2019/09/29 PHP
深入理解JavaScript系列(8) S.O.L.I.D五大原则之里氏替换原则LSP
2012/01/15 Javascript
JavaScript设计模式之原型模式(Object.create与prototype)介绍
2014/12/28 Javascript
Javascript 拖拽雏形(逐行分析代码,让你轻松了拖拽的原理)
2015/01/23 Javascript
jQuery的remove()方法使用详解
2015/08/11 Javascript
详解Angular 4.x Injector
2017/05/04 Javascript
利用Ionic2 + angular4实现一个地区选择组件
2017/07/27 Javascript
BootStrap入门学习第一篇
2017/08/28 Javascript
JS验证输入的是否是数字及保留几位小数问题
2018/05/09 Javascript
解决vue组件props传值对象获取不到的问题
2019/06/06 Javascript
在微信小程序中使用mqtt服务的方法
2019/12/13 Javascript
python 获取et和excel的版本号
2009/04/09 Python
给Python入门者的一些编程建议
2015/06/15 Python
Python使用pygame模块编写俄罗斯方块游戏的代码实例
2015/12/08 Python
Python简单实现安全开关文件的两种方式
2016/09/19 Python
老生常谈python的私有公有属性(必看篇)
2017/06/09 Python
pycharm下打开、执行并调试scrapy爬虫程序的方法
2017/11/29 Python
Python实现的双色球生成功能示例
2017/12/18 Python
Python使用pickle模块储存对象操作示例
2018/08/15 Python
使用python批量化音乐文件格式转换的实例
2019/01/09 Python
简单了解python代码优化小技巧
2019/07/08 Python
浅析Python 引号、注释、字符串
2019/07/25 Python
Pytorch中Tensor与各种图像格式的相互转化详解
2019/12/26 Python
Python中bisect的使用方法
2019/12/31 Python
CSS3实现网站商品展示效果图
2020/01/18 HTML / CSS
MANGO官方网站:西班牙芒果服装品牌
2017/01/15 全球购物
如何开启linux的ssh服务
2015/02/14 面试题
化工专业大学生职业生涯规划书
2014/01/14 职场文书
国际商务专业职业生涯规划书范文
2014/01/17 职场文书
幼儿园运动会口号
2014/06/07 职场文书
岗位职责说明书模板
2014/07/30 职场文书
论文答辩开场白大全
2015/05/27 职场文书
nginx结合openssl实现https的方法
2021/07/25 Servers
Nginx静态压缩和代码压缩提高访问速度详解
2022/05/30 Servers