SQL语句中JOIN的用法
记录:257
写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数据:
查看TEST_TB02数据:
1.在SQL中使用JOIN
TEST_TB01和TEST_TB02根据part_id使用JOIN连接,只返回两个表(TEST_TB01和TEST_TB02)中连接字段相等的记录。
SQL语句:
SELECT*
FROMTEST_TB01 aa
JOIN TEST_TB02 bbON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;
执行结果:
2.在SQL中使用INNER JOIN
TEST_TB01和TEST_TB02根据part_id使用INNER JOIN连接,只返回两个表(TEST_TB01和TEST_TB02)中连接字段相等的记录。INNER JOIN和JOIN效果等价。
SQL语句:
SELECT*
FROMTEST_TB01 aa
INNER JOIN TEST_TB02 bbON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;
执行结果:
3.在SQL中使用LEFT JOIN
TEST_TB01和TEST_TB02根据part_id使用LEFT JOIN连接,左连接,返回左表(TEST_TB01)中所有的记录以及右表(TEST_TB02)中连接字段相等的记录。
SQL语句:
SELECT*
FROMTEST_TB01 aa
LEFT JOIN TEST_TB02 bbON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;
执行结果:
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*
FROMTEST_TB01 aa
LEFT OUTER JOIN TEST_TB02 bbON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;
执行结果:
5.在SQL中使用RIGHT JOIN
TEST_TB01和TEST_TB02根据part_id使用RIGHT JOIN连接,右连接,返回右表(TEST_TB02)中所有的记录以及左表(TEST_TB01)中连接字段相等的记录
SQL语句:
SELECT*
FROMTEST_TB01 aa
RIGHT JOIN TEST_TB02 bbON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;
执行结果:
6.在SQL中使用FULL JOIN
TEST_TB01和TEST_TB02根据part_id使用FULL JOIN连接,外连接,返回两个表中的行:LEFT JOIN + RIGHT JOIN所有行记录。
SQL语句:
SELECT*
FROMTEST_TB01 aa
FULL JOIN TEST_TB02 bbON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;
执行结果:
四、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数据:
查看TEST_TB02数据:
1.在SQL中使用JOIN
TEST_TB01和TEST_TB02根据part_id使用JOIN连接,只返回两个表(TEST_TB01和TEST_TB02)中连接字段相等的记录。
SQL语句:
SELECT*
FROMTEST_TB01 aa
JOIN TEST_TB02 bbON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;
执行结果:
2.在SQL中使用INNER JOIN
TEST_TB01和TEST_TB02根据part_id使用INNER JOIN连接,只返回两个表(TEST_TB01和TEST_TB02)中连接字段相等的记录。INNER JOIN和JOIN效果等价。
SQL语句:
SELECT*
FROMTEST_TB01 aa
INNER JOIN TEST_TB02 bbON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;
执行结果:
3.在SQL中使用LEFT JOIN
TEST_TB01和TEST_TB02根据part_id使用LEFT JOIN连接,左连接,返回左表(TEST_TB01)中所有的记录以及右表(TEST_TB02)中连接字段相等的记录。
SQL语句:
SELECT*
FROMTEST_TB01 aa
LEFT JOIN TEST_TB02 bbON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;
执行结果:
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*
FROMTEST_TB01 aa
LEFT OUTER JOIN TEST_TB02 bbON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;
执行结果:
5.在SQL中使用RIGHT JOIN
TEST_TB01和TEST_TB02根据part_id使用RIGHT JOIN连接,右连接,返回右表(TEST_TB02)中所有的记录以及左表(TEST_TB01)中连接字段相等的记录
SQL语句:
SELECT*
FROMTEST_TB01 aa
RIGHT JOIN TEST_TB02 bbON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;
执行结果:
6.在SQL中使用FULL JOIN
TEST_TB01和TEST_TB02根据part_id使用FULL JOIN连接,外连接,返回两个表中的行:LEFT JOIN + RIGHT JOIN所有行记录。
SQL语句:
SELECT*
FROMTEST_TB01 aa
FULL JOIN TEST_TB02 bbON aa.part_id = bb.part_id
ORDER BY aa.sensor_id ASC;
执行结果:
五、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语句中EXISTS的用法
记录:258 在业务开展中,会遇到类似需求. 需求1:UPDATE表TEST_TB01中的记录:满足条件:这些记录不在TEST_TB02中. 需求2:UPDATE表TEST_TB01中的记录:满足条件 ...
- IsNull 和 SQL语句中CASE WHEN用法
[转]IsNull 和 SQL语句中CASE WHEN用法收藏 [转]IsNull 和 SQL语句中CASE WHEN用法 1.ISNULL 使用指定的替换值替换 NULL. ...
- sql语句中的in用法示例_PHP中的循环语句和示例
sql语句中的in用法示例 循环 (Loops) Imagine that we need a program that says "hello world" 100 times. ...
- sql语句中的in用法示例_示例中JavaScript in操作符
sql语句中的in用法示例 One of the first topics you'll come across when learning JavaScript (or any other prog ...
- mysql语句中limt_mysql sql语句中的limit用法
mysql sql语句中的limit用法 1.select * from tablename limit 100,15 从100条记录后开始(不包括第100条记录)取出15条记录 (实际取出的是第 1 ...
- sql语句中的limit用法
sql语句中的limit用法 limit 用于限制查询结果返回. 用法: limit a,b 其中a表示查询数据的起始位置,b表示返回的数量. (MySQL数据库中的记录是从0开始的) 举例: SEL ...
- SQL语句中Cast的用法
GPS平台.网站建设.软件开发.系统运维,找森大网络科技! https://cnsendnet.taobao.com 来自森大科技官方博客 http://www.cnsendblog.com/inde ...
- finereport报表设计中模板数据集的sql语句中if的用法_报表工具中动态参数的灵活运用...
报表开发过程中,有的时候我们会觉得普通参数很难满足一些业务需求,比如第二个数据集要引用第一个数据集的结果进行计算,动态控制 SQL 的过滤条件,动态列等,如果您遇到了这种情况,可以尝试使用动态参数即 ...
- SQL语句中IN的用法
具体的逻辑是:文件分不同的DocTypeID即文件的类型 如果对文件进行处理比如说 银行等部门对单据先要进行扫描然后录入 校对等处理,那么就要分为不同的批次即不同的BatchNum 在这BatchNu ...
最新文章
- 3 OC 属性和方法
- SecureRandom
- UA PHYS515 电磁理论I 麦克斯韦方程组基础3 麦克斯韦方程的势能形式
- 轻松了解“Web应用防火墙”
- Listview中使用线程实现无限加载更多项目的功能
- python学习笔记--迭代
- js(Dom+Bom)第七天(1)
- oracle内存参数越大越好吗,什么是Oracle内存参数调优技术?
- 用三年时间培养 1W 名高素质技术人才,这是一个什么样的计划?
- Golang 变量申明方式
- 回溯法 - 递归 - n皇后问题 - 所有解
- 《大数据技术原理与应用》第一章-大数据概述
- 有监督学习、无监督学习和半监督学习的分类
- 用golang从企业微信里获取打卡记录的方法
- 从今天起,我决定去掉cnzz统计
- flyingsaucer转换多个html,使用 itext、flying-saucer 实现html转PDF
- elasticsearch最大节点数_记录 Elasticsearch 的 maximum shards open 问题
- 【安全牛学习笔记】密钥交换、AIRCRACK-NG基础、AIRODUMP-NG排错
- psid mysql_eclipse连接MYSQL,保存数据到mysql里,哪出错了?
- mysql地理坐标_mysql中如何将地理坐标拆成经度和纬度两份?
热门文章
- python发微信语音没声音怎么回事_苹果手机微信语音没声音怎么回事?
- IOS,Android-Facebook分享
- html中加入js判断,javascript 如何判断字符串中是否有html代码/标签
- 搭建一个几千左右并发的网站实践过程
- 能力素质有所欠缺_心理测试:你会去拿哪一窝金蛋,测你赚钱的能力有多强
- 心理学教授谈记忆魔法--艾宾浩斯遗忘曲线(转帖)
- python粒子特效_Ren'Py引擎从入门到放弃(支线3)——简单粒子效果
- 如何使 Mysql自动生成序号列,序号自动增长
- [power bi]calculate
- 挽救损坏的 Word 文档