背景:业务场景中有个任务每天运行一次,在第二个月的时候,需要把上一个月的某个任务每天重跑一次。
正常情况下,需要在第二个月,手动补数据,选择补数据时间为上个月第一天到最后一天,重跑即可。由于不想每个月都手动重跑,查了下ODPS文档,觉得for-each这个功能应该是能满足需求。
具体实现过程:
1、定义一个日期表,包含月份和日期
CREATE TABLE IF NOT EXISTS dim_everyday
(
month STRING COMMENT '月份,yyyyMM',
day STRING COMMENT '日期,yyyyMMdd'
)
COMMENT '存放每天日期,维度表';
2、做一个定时任务,每天向表中插入前一天日期数据
insert overwrite table dim_everyday
SELECT month,day FROM dim_everyday
UNION
SELECT TO_CHAR(TO_DATE('${bizdate}','yyyymmdd'),'yyyymm'),TO_CHAR(TO_DATE('${bizdate}','yyyymmdd'),'yyyymmdd');
3、定义一个赋值节点get_everyday,赋值语言选择ODPS SQL,主要是取dim_everyday中上月每天的日期数据
SELECT day
FROM dim_everyday
WHERE day>=TO_CHAR(TO_DATE(CONCAT('${lastMonth}', '01'), 'yyyymmdd'),'yyyymmdd')
AND day<=TO_CHAR(DATEADD(DATEADD(TO_DATE(CONCAT('${lastMonth}', '01'), 'yyyymmdd'),1,'mm'), - 1,'dd') ,'yyyymmdd');
4、定义for-each节点
里面包含每天需要运行的节点
在计算的时候使用'${dag.foreach.current}'表示获取循环节点的日期。具体可以参考这篇文章https://help.aliyun.com/document_detail/137529.html?spm=5176.11065259.1996646101.searchclickresult.358a335eGaGMRw
SELECT provider_id
,region_code
,operator_code
,current_price
,ROW_NUMBER() OVER (PARTITION BY provider_id, region_code,operator_code ORDER BY effective_date DESC) AS rn
FROM tb1
WHERE DATEDIFF(to_date('${dag.foreach.current}','yyyyMMdd'),effective_date,'dd') >= 0
5、定义整个任务调度时间为每月调度一次
这样就可以每个月自动重跑上个月每天的数据