背景
上游业务系统的表,批量truncate然后insert,任务失败,导致数仓ods层抽取数据为空(记录行为0)。该表为组织架构维度表,下游大量数据模型依赖该表,导致大量数据异常,影响BI用户体验。
方案
- 方案1: 调度工具,做判断,如果当日抽取上游表数据为空,则取昨天的ods层数据(组织架构的维度表,变化频率不高)。但是,购买的数据开发平台,调度工具不支持类似的分支判断。Dophinscheduler提供了类似功能。
- 方案2: 使用shell脚本,SQL判断当日上游数据情况,如果为空,则使用昨日ODS层数据。shell脚本中调用SQL语句,比较麻烦,需要配置hive的keberos认证。不够优雅。
- 方案3: 直接使用HSQL实现这种IF ELSE判断逻辑,如果当日抽取的上游表数据为空,则取昨天的ODS层的数据。该方案直接使用平台的调度,和已集成的keberos认证。比较完美,但是如何实现这样的逻辑呢?
实现
假设DataX抽取的ODS层表名为; o_hcm.org_unit_record_stg. ods层表名为:o_hcm.org_unit_record.
- 普通程序判断逻辑
if select count(1) from o_hcm.org_unit_record_stg == 0
select * from o_hcm.org_unit_record
else
select * from o_hcm.org_unit_record_stg
- SQL实现
SELECT *
FROM (
SELECT COUNT(1) AS cnt FROM o_hcm.org_unit_record_stg
) t1
INNER JOIN o_hcm.org_unit_record t2 ON t1.cnt = 0 -- 匹配 org_unit_record_stg 空时;
UNION ALL
SELECT * FROM o_hcm.org_unit_record_stg t1; -- 匹配 org_unit_record_stg 不为空时;
;
利用INNER JOIN方式,获取org_unit_record的数据。
扩展思考
- 是否所有的IF ELSE 模式,都可以用union all + 笛卡尔积/JOIN等方式构造出来?