(二)ODS层更新:源表和目标表,没有last_update,比对取增量,却重复抽到某部分数据,怎么解决?
源表和目标表,比对的时候,某部分数据,每次比对都被认为是“新数据”,然后每次抽取比对都会被过滤到目标表,从而造成目标表有很多重复数据,是什么原因呢?原因是该表的多个字段“数据缺失严重”,我们比对数据前是已经给空值/空格填了默认值,也就是说这些被填充过的字段,是有很多重复值的。我们联表查询时,关联字段时有重复值时,那这次查询肯定会发散,而我们用的kettle【合并记录】插件的原理也是联表查询。
我的上一篇文章《ODS层更新:如果源数据没有“更新时间“字段,如何作增量抽取?我都踩过这些坑》提到用来联表的字段,一定是该条的数据的唯一标识。如果不是的话,那就造一个,多个字段作为“关联字段”避免发散。如果一条数据,10个字段,7个字段缺失,你怎么造“唯一标识”,最后联表比对时,还是会发散。也就是说,联表时,某部分数据字段值缺失严重,多对多联表是有风险的,那有没有其他取增量更优的解决方案呢?
即然多对多联表有风险,那就一对一联表,不就解决了吗?
- 取增量思路:
源表
LEFT OUTER JOIN
目标表
WHERE 目标表.关联字段 IS NULL - 建【源表】
CREATE TABLE work_exper(
id NUMBER(10),
name VARCHAR2(10),
company VARCHAR2(10),
job VARCHAR2(10),
work_start_date date,
work_end_date date
);
- 给【源表】插入数据
INSERT INTO work_exper VALUES(1001,'丧彪','百度','清洁工',to_date('1997-05-17','yyyy-mm-dd'),to_date('1998-08-15','yyyy-mm-dd'));
INSERT INTO work_exper VALUES(1001,'丧彪','腾讯','保安',to_date('1998-09-17','yyyy-mm-dd'),to_date('1999-12-15','yyyy-mm-dd'));
INSERT INTO work_exper VALUES(1001,'丧彪','阿里','炊事员',to_date('2000-07-17','yyyy-mm-dd'),to_date('2002-03-18','yyyy-mm-dd'));
INSERT INTO work_exper VALUES(1002,'段坤','快手','运营专员',to_date('1996-08-27','yyyy-mm-dd'),to_date('1998-02-08','yyyy-mm-dd'));
INSERT INTO work_exper VALUES(1002,'段坤','抖音','主播',to_date('1997-01-17','yyyy-mm-dd'),to_date('1998-02-14','yyyy-mm-dd'));
INSERT INTO work_exper VALUES(1002,'段坤','爱奇艺','COO',to_date('1999-05-19','yyyy-mm-dd'),to_date('2008-08-15','yyyy-mm-dd'));
INSERT INTO work_exper VALUES(1003,'阿祖','建行','催收员',to_date('2001-05-17','yyyy-mm-dd'),to_date('2018-04-12','yyyy-mm-dd'));
INSERT INTO work_exper VALUES(1001,'丧彪','阿里','炊事班长',to_date('2003-07-17','yyyy-mm-dd'),to_date('2020-03-18','yyyy-mm-dd'));
- 查询【源表】:
SELECT id,name,job,work_start_date,work_end_date
FROM work_exper
从上面的源表来看,字段ID+NAME+COMPANY+JOB就可以确定为该行数据的唯一标识了,但这是“多对多联表”,现实的业务场景,数据可不是那么规整的,一定是有很多缺失值的,所以我们如何作“一对一联表”呢?
- 用窗口函数row_number()over()给源数据造一个唯一标识
一个员工只有一个ID,但有多条工作记录,那我们可以以“ID"进行分组,在组内进行排序,最终将ID+排序结果,这样便可以得到"唯一标识"
SELECT id||'_'||row_number()over(partition by id order by company,job,work_start_date,work_end_date) as pk_id ,id,name,job,work_start_date,work_end_date
FROM work_exper
接下来建ods层目标表
- 建ods层【目标表】
CREATE TABLE ods_work_exper(
pk_id VARCHAR2(10),
id NUMBER(10),
name VARCHAR2(10),
company VARCHAR2(10),
job VARCHAR2(10),
work_start_date date,
work_end_date date
);
你可以看出,我并没有给字段pk_id建立“唯一主键约束”,也就是说我允许目标中出现重复的pk_id。为什么这样做呢?因为id分组组内排序是动态的,难免会出现有一天新数据的pk_id 和某条旧数据的pk_id一样,但其他字段不一样的。所以我们取增量的脚本可以改进成。
取增量思路改进:
源表
LEFT OUTER JOIN
目标表
WHERE 目标表.关联字段 IS NULL
OR 源表.字段 <>目标表字段.字段脚本实例:
SELECTA.pk_id ,A.id,A.name,A.company,A.job,A.work_start_date,A.work_end_date
FROM
(SELECTid||'_'||row_number()over(partition by id order by company,job,work_start_date,work_end_date) as pk_id , id, name, company, job, work_start_date, work_end_dateFROMwork_exper
) A --源表
LEFT OUTER JOINods_work_exper B --目标表
ON A.pk_id = B.pk_id
WHERE B.pk_id IS NULLOR A.name <> B.nameOR A.company <> B.companyOR A.job <> B.jobOR A.work_start_date <> B.work_start_dateOR A.work_end_date <> B.work_end_date
实际的业务场景中,源表和目标表都是来自不同的数据库。如果源数据库没有赋权的情况下,异构数据联表查询是实现不了的。我们可以借助kettle的【记录集连接】插件
(流程概览)
- 1.1 源表:work_exper
- 1.2目标表:ods_work_exper
- 2.记录集连接
- 3.过滤记录
- 4.获取系统信息:给新增数据增加“last_update"字段
- 5.新增数据插入目标表:ods_work_exper
(二)ODS层更新:源表和目标表,没有last_update,比对取增量,却重复抽到某部分数据,怎么解决?相关推荐
- python对比excel两列数据_python 对比excel表格数据表-python实现两个excel表列数据对比若源表与目标表存......
在数据分析方面,比起python,excel的局限性在哪 data3 = pandas.merge(data1, data2, on=['名称'], how='inner') inner:内连接,取交 ...
- hive血缘关系之输入表与目标表的解析
接了一个新需求:需要做数据仓库的血缘关系.正所谓兵来将挡水来土掩,那咱就动手吧. 血缘关系是数据治理的一块,其实有专门的第三方数据治理框架,但考虑到目前的线上环境已经趋于稳定,引入新的框架无疑是劳民伤 ...
- Mysql 数据血缘关系图_hive血缘关系之输入表与目标表的解析
接了一个新需求:需要做数据仓库的血缘关系.正所谓兵来将挡水来土掩,那咱就动手吧. 血缘关系是数据治理的一块,其实有专门的第三方数据治理框架,但考虑到目前的线上环境已经趋于稳定,引入新的框架无疑是劳民伤 ...
- oracle指定源位置怎么弄,ORACLE Goldengate测试解决源端和目标端表结构字段位置不同的2种实现方法...
测试环境: 源端操作系统:rhel5.6 目标端操作系统:windows2008 R2 源和目标使用的数据版本均为:11.2.0.4.0 一.先模拟问题现象 源和目标端搭建好OGG软件和oracle数 ...
- Kali 2017更新源
一.添加更新源 leafpad /etc/apt/sources.list 二.国内更新源 #autodeb http://http.kali.org/kali kali-rolling main n ...
- mysql++快速复制大表_MySql数据库表快速复制
表索引操作 这里之所以写索引的操作主要原因在于:在导入数据前删除索引能大大提升导入速度. DDL语句获取现有索引1show create table t_question_bak; 获取所有索引 获取 ...
- DJango周总结二:模型层,单表,多表操作,连表操作,数据库操作,事务
django周复习二 1,模型层: 1单表操作: 13个必会操作总结 返回QuerySet对象的方法有 all() filter() exclude() ...
- 编写Scala代码,使用Spark讲Mysql数据表中的数据抽取到Hive的ODS层
编写Scala代码,使用Spark讲Mysql数据表中的数据抽取到Hive的ODS层 抽取MySQL的metast库中Production表的全量数据进入Hive的ods库中表production,字 ...
- Mybatis源码分析--关联表查询及延迟加载原理(二)
在上一篇博客Mybatis源码分析--关联表查询及延迟加载(一)中我们简单介绍了Mybatis的延迟加载的编程,接下来我们通过分析源码来分析一下Mybatis延迟加载的实现原理. 其实简单来说Myba ...
最新文章
- SPOJ375(树链剖分)
- 合并两个对象 java_在Java中合并两个对象列表8
- 皮一皮:真是个看脸的年代...
- cisco 6509交换配置
- java bean的反射类_JAVA中反射机制五(JavaBean的内省与BeanUtils库)
- 智能外呼系统相关资料总结
- 【图解漏洞】图解跨站请求伪造(CSRF)原理
- 三星Galaxy S22全系售价曝光:标准版起步或超5000元
- Machine Learning - XIV. Dimensionality Reduction降维 (Week 8)
- 第三季-第4课-Linux应用程序地址布局
- python xpath 中文乱码_Python爬虫实战 批量下载高清美女图片!让你们开开眼!
- Python使用打码平台进行识别验证码
- Webpack打包UMD的export要带default访问问题
- IT项目经理面试题分解
- 如何将WebRoot部署到tomcat中
- 数组常用操作。以逗号隔开、以逗号+单引号隔开、转List等
- 中小银行数字普惠金融发展的思考和建议
- ff6全部青魔法获得(不走兽之原)
- Docker之工作中常用的命令(二)
- win 32 学习笔记(十) 对话框