Ver código fonte

fix(ods): 16 张 SQL inner dt 锚点用 COALESCE(update_time, create_time) 兜底

inner 三处(ods_dt / PARTITION BY / ORDER BY)+ 调度版 dt filter 加兜底;
外层 update_time 字段保留 raw NULL 语义;init 版头部备注同步刷新。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
tianyu.chu 20 horas atrás
pai
commit
ade9b62fa8

+ 5 - 5
jobs/ods/prd/ods_prd_checklist_base_info_inc_d.sql

@@ -1,7 +1,7 @@
 -- 作者:tianyu.chu
 -- 日期:2026-05-07
 -- 工单:(无)
--- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(update_time)=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
+-- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(COALESCE(update_time, create_time))=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
 -- 状态:[草案]
 -- 备注:sched=T,${dt}=业务日 T-1(yyyyMMdd),${pdt}=T-2
 
@@ -47,13 +47,13 @@ SELECT
     ods_dt                               AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM raw.raw_prd_checklist_base_info_inc_d
     WHERE dt IN ('${dt}', '${pdt}')
-      AND DATE_FORMAT(update_time, 'yyyyMMdd') = '${dt}'
+      AND DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') = '${dt}'
 ) t
 WHERE t.rn = 1;

+ 5 - 5
jobs/ods/prd/ods_prd_panini_checklist_base_info_inc_d.sql

@@ -1,7 +1,7 @@
 -- 作者:tianyu.chu
 -- 日期:2026-05-07
 -- 工单:(无)
--- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(update_time)=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
+-- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(COALESCE(update_time, create_time))=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
 -- 状态:[草案]
 -- 备注:sched=T,${dt}=业务日 T-1(yyyyMMdd),${pdt}=T-2
 
@@ -44,13 +44,13 @@ SELECT
     ods_dt                                    AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM raw.raw_prd_panini_checklist_base_info_inc_d
     WHERE dt IN ('${dt}', '${pdt}')
-      AND DATE_FORMAT(update_time, 'yyyyMMdd') = '${dt}'
+      AND DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') = '${dt}'
 ) t
 WHERE t.rn = 1;

+ 5 - 5
jobs/ods/prd/ods_prd_panini_checklist_version_config_inc_d.sql

@@ -1,7 +1,7 @@
 -- 作者:tianyu.chu
 -- 日期:2026-05-07
 -- 工单:(无)
--- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(update_time)=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
+-- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(COALESCE(update_time, create_time))=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
 -- 状态:[草案]
 -- 备注:sched=T,${dt}=业务日 T-1(yyyyMMdd),${pdt}=T-2
 
@@ -44,13 +44,13 @@ SELECT
     ods_dt                                     AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM raw.raw_prd_panini_checklist_version_config_inc_d
     WHERE dt IN ('${dt}', '${pdt}')
-      AND DATE_FORMAT(update_time, 'yyyyMMdd') = '${dt}'
+      AND DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') = '${dt}'
 ) t
 WHERE t.rn = 1;

+ 5 - 5
jobs/ods/shp/ods_shp_tzy_merchant_info_inc_d.sql

@@ -1,7 +1,7 @@
 -- 作者:tianyu.chu
 -- 日期:2026-05-07
 -- 工单:(无)
--- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(update_time)=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
+-- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(COALESCE(update_time, create_time))=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
 -- 状态:[草案]
 -- 备注:sched=T,${dt}=业务日 T-1(yyyyMMdd),${pdt}=T-2
 
@@ -61,13 +61,13 @@ SELECT
     ods_dt                                 AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM raw.raw_shp_tzy_merchant_info_inc_d
     WHERE dt IN ('${dt}', '${pdt}')
-      AND DATE_FORMAT(update_time, 'yyyyMMdd') = '${dt}'
+      AND DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') = '${dt}'
 ) t
 WHERE t.rn = 1;

+ 5 - 5
jobs/ods/trd/ods_trd_card_group_info_inc_d.sql

@@ -1,7 +1,7 @@
 -- 作者:tianyu.chu
 -- 日期:2026-05-07
 -- 工单:(无)
--- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(update_time)=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
+-- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(COALESCE(update_time, create_time))=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
 -- 状态:[草案]
 -- 备注:sched=T,${dt}=业务日 T-1(yyyyMMdd),${pdt}=T-2;ods 跨 dt 不去重,同 pk 多 dt 并存(拉链表底层)
 
@@ -126,13 +126,13 @@ SELECT
     ods_dt                                              AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM raw.raw_trd_card_group_info_inc_d
     WHERE dt IN ('${dt}', '${pdt}')
-      AND DATE_FORMAT(update_time, 'yyyyMMdd') = '${dt}'
+      AND DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') = '${dt}'
 ) t
 WHERE t.rn = 1;

+ 5 - 5
jobs/ods/trd/ods_trd_card_group_order_info_inc_d.sql

@@ -1,7 +1,7 @@
 -- 作者:tianyu.chu
 -- 日期:2026-05-07
 -- 工单:(无)
--- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(update_time)=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
+-- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(COALESCE(update_time, create_time))=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
 -- 状态:[草案]
 -- 备注:sched=T,${dt}=业务日 T-1(yyyyMMdd),${pdt}=T-2;ods 跨 dt 不去重,同 pk 多 dt 并存(拉链表底层);
 --       订单表 his_o 历史灌入由 manual/backfill/ods_trd_card_group_order_info_init.sql 一次性处理,本调度只读 inc_d
@@ -103,13 +103,13 @@ SELECT
     ods_dt                                           AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM raw.raw_trd_card_group_order_info_inc_d
     WHERE dt IN ('${dt}', '${pdt}')
-      AND DATE_FORMAT(update_time, 'yyyyMMdd') = '${dt}'
+      AND DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') = '${dt}'
 ) t
 WHERE t.rn = 1;

+ 5 - 5
jobs/ods/usr/ods_usr_app_base_user_inc_d.sql

@@ -1,7 +1,7 @@
 -- 作者:tianyu.chu
 -- 日期:2026-05-07
 -- 工单:(无)
--- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(update_time)=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
+-- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(COALESCE(update_time, create_time))=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
 -- 状态:[草案]
 -- 备注:sched=T,${dt}=业务日 T-1(yyyyMMdd),${pdt}=T-2;ods 跨 dt 不去重,同 pk 多 dt 并存(拉链表底层)
 
@@ -63,13 +63,13 @@ SELECT
     ods_dt                                          AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM raw.raw_usr_app_base_user_inc_d
     WHERE dt IN ('${dt}', '${pdt}')
-      AND DATE_FORMAT(update_time, 'yyyyMMdd') = '${dt}'
+      AND DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') = '${dt}'
 ) t
 WHERE t.rn = 1;

+ 5 - 5
jobs/ods/usr/ods_usr_app_user_cert_info_inc_d.sql

@@ -1,7 +1,7 @@
 -- 作者:tianyu.chu
 -- 日期:2026-05-07
 -- 工单:(无)
--- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(update_time)=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
+-- 目的:raw → ods 增量同步(ADR-03);双源 union (raw dt=${dt} + raw dt=${pdt}) + DATE_FORMAT(COALESCE(update_time, create_time))=${dt} 过滤 + (id, ods_dt) dedupe + 动态分区写入
 -- 状态:[草案]
 -- 备注:sched=T,${dt}=业务日 T-1(yyyyMMdd),${pdt}=T-2;本表软删字段为 del_flag(其它表多为 del_flg)
 
@@ -22,13 +22,13 @@ SELECT
     ods_dt                           AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM raw.raw_usr_app_user_cert_info_inc_d
     WHERE dt IN ('${dt}', '${pdt}')
-      AND DATE_FORMAT(update_time, 'yyyyMMdd') = '${dt}'
+      AND DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') = '${dt}'
 ) t
 WHERE t.rn = 1;

+ 5 - 6
manual/backfill/20260507_ods_prd_checklist_base_info_inc_d_init.sql

@@ -1,10 +1,9 @@
 -- 作者:tianyu.chu
 -- 日期:2026-05-07
 -- 工单:(无)
--- 目的:ods_prd_checklist_base_info ods 初始化一次性灌入:raw 单表全部历史 dt → DATE(update_time) 归位 → ods 各 dt 分区
+-- 目的:ods_prd_checklist_base_info ods 初始化一次性灌入:raw 单表全部历史 dt → DATE(COALESCE(update_time, create_time)) 归位 → ods 各 dt 分区
 -- 状态:[待执行]
--- 备注:跑一次后由 jobs/ods/prd/ods_prd_checklist_base_info_inc_d.sql 接管日常增量;
---       update_time 为空的行落入 __HIVE_DEFAULT_PARTITION__(非阻塞,下游自行处理)
+-- 备注:跑一次后由 jobs/ods/prd/ods_prd_checklist_base_info_inc_d.sql 接管日常增量
 
 -- 动态分区上限:本表跨多年 dt 撞 hive 默认 1000/100。
 -- pernode 指 Spark task 节点(spark.sql.shuffle.partitions=200)不是物理 worker。
@@ -54,10 +53,10 @@ SELECT
     ods_dt                               AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM raw.raw_prd_checklist_base_info_inc_d
 ) t

+ 5 - 6
manual/backfill/20260507_ods_prd_panini_checklist_base_info_inc_d_init.sql

@@ -1,10 +1,9 @@
 -- 作者:tianyu.chu
 -- 日期:2026-05-07
 -- 工单:(无)
--- 目的:ods_prd_panini_checklist_base_info ods 初始化一次性灌入:raw 单表全部历史 dt → DATE(update_time) 归位 → ods 各 dt 分区
+-- 目的:ods_prd_panini_checklist_base_info ods 初始化一次性灌入:raw 单表全部历史 dt → DATE(COALESCE(update_time, create_time)) 归位 → ods 各 dt 分区
 -- 状态:[待执行]
--- 备注:跑一次后由 jobs/ods/prd/ods_prd_panini_checklist_base_info_inc_d.sql 接管日常增量;
---       update_time 为空的行落入 __HIVE_DEFAULT_PARTITION__(非阻塞,下游自行处理)
+-- 备注:跑一次后由 jobs/ods/prd/ods_prd_panini_checklist_base_info_inc_d.sql 接管日常增量
 
 -- 动态分区上限:本表跨多年 dt 撞 hive 默认 1000/100。
 -- pernode 指 Spark task 节点(spark.sql.shuffle.partitions=200)不是物理 worker。
@@ -51,10 +50,10 @@ SELECT
     ods_dt                                    AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM raw.raw_prd_panini_checklist_base_info_inc_d
 ) t

+ 5 - 6
manual/backfill/20260507_ods_prd_panini_checklist_version_config_inc_d_init.sql

@@ -1,10 +1,9 @@
 -- 作者:tianyu.chu
 -- 日期:2026-05-07
 -- 工单:(无)
--- 目的:ods_prd_panini_checklist_version_config ods 初始化一次性灌入:raw 单表全部历史 dt → DATE(update_time) 归位 → ods 各 dt 分区
+-- 目的:ods_prd_panini_checklist_version_config ods 初始化一次性灌入:raw 单表全部历史 dt → DATE(COALESCE(update_time, create_time)) 归位 → ods 各 dt 分区
 -- 状态:[待执行]
--- 备注:跑一次后由 jobs/ods/prd/ods_prd_panini_checklist_version_config_inc_d.sql 接管日常增量;
---       update_time 为空的行落入 __HIVE_DEFAULT_PARTITION__(非阻塞,下游自行处理)
+-- 备注:跑一次后由 jobs/ods/prd/ods_prd_panini_checklist_version_config_inc_d.sql 接管日常增量
 
 -- 动态分区上限:本表跨多年 dt 撞 hive 默认 1000/100。
 -- pernode 指 Spark task 节点(spark.sql.shuffle.partitions=200)不是物理 worker。
@@ -51,10 +50,10 @@ SELECT
     ods_dt                                     AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM raw.raw_prd_panini_checklist_version_config_inc_d
 ) t

+ 5 - 6
manual/backfill/20260507_ods_shp_tzy_merchant_info_inc_d_init.sql

@@ -1,10 +1,9 @@
 -- 作者:tianyu.chu
 -- 日期:2026-05-07
 -- 工单:(无)
--- 目的:ods_shp_tzy_merchant_info ods 初始化一次性灌入:raw 单表全部历史 dt → DATE(update_time) 归位 → ods 各 dt 分区
+-- 目的:ods_shp_tzy_merchant_info ods 初始化一次性灌入:raw 单表全部历史 dt → DATE(COALESCE(update_time, create_time)) 归位 → ods 各 dt 分区
 -- 状态:[待执行]
--- 备注:跑一次后由 jobs/ods/shp/ods_shp_tzy_merchant_info_inc_d.sql 接管日常增量;
---       update_time 为空的行落入 __HIVE_DEFAULT_PARTITION__(非阻塞,下游自行处理)
+-- 备注:跑一次后由 jobs/ods/shp/ods_shp_tzy_merchant_info_inc_d.sql 接管日常增量
 
 -- 动态分区上限:本表跨多年 dt 撞 hive 默认 1000/100。
 -- pernode 指 Spark task 节点(spark.sql.shuffle.partitions=200)不是物理 worker。
@@ -68,10 +67,10 @@ SELECT
     ods_dt                                 AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM raw.raw_shp_tzy_merchant_info_inc_d
 ) t

+ 5 - 6
manual/backfill/20260507_ods_trd_card_group_info_inc_d_init.sql

@@ -1,10 +1,9 @@
 -- 作者:tianyu.chu
 -- 日期:2026-05-07
 -- 工单:(无)
--- 目的:ods_trd_card_group_info ods 初始化一次性灌入:raw 单表全部历史 dt → DATE(update_time) 归位 → ods 各 dt 分区
+-- 目的:ods_trd_card_group_info ods 初始化一次性灌入:raw 单表全部历史 dt → DATE(COALESCE(update_time, create_time)) 归位 → ods 各 dt 分区
 -- 状态:[待执行]
--- 备注:跑一次后由 jobs/ods/trd/ods_trd_card_group_info_inc_d.sql 接管日常增量;
---       update_time 为空的行落入 __HIVE_DEFAULT_PARTITION__(非阻塞,下游自行处理)
+-- 备注:跑一次后由 jobs/ods/trd/ods_trd_card_group_info_inc_d.sql 接管日常增量
 
 -- 动态分区上限:本表跨多年 dt 撞 hive 默认 1000/100。
 -- pernode 指 Spark task 节点(spark.sql.shuffle.partitions=200)不是物理 worker。
@@ -133,10 +132,10 @@ SELECT
     ods_dt                                              AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM raw.raw_trd_card_group_info_inc_d
 ) t

+ 5 - 6
manual/backfill/20260507_ods_trd_card_group_order_info_inc_d_init.sql

@@ -2,11 +2,10 @@
 -- 日期:2026-05-07
 -- 工单:(无)
 -- 目的:订单表 ods 初始化一次性灌入:raw_his_o(存量历史)+ raw_inc_d(已跑全部增量)UNION ALL,
---       按 DATE_FORMAT(update_time, 'yyyyMMdd') 归位到 ods 各 dt 分区,(id, ods_dt) dedupe,动态分区写入
+--       按 DATE_FORMAT(COALESCE(update_time, create_time), 'yyyyMMdd') 归位到 ods 各 dt 分区,(id, ods_dt) dedupe,动态分区写入
 -- 状态:[待执行]
 -- 备注:跑一次后由 jobs/ods/trd/ods_trd_card_group_order_info_inc_d.sql 接管日常增量;
---       his_o + inc_d schema 完全一致(91 字段 STRING),SELECT * UNION ALL 安全;
---       update_time 为空的行落入 __HIVE_DEFAULT_PARTITION__(非阻塞,下游自行处理)
+--       his_o + inc_d schema 完全一致(91 字段 STRING),SELECT * UNION ALL 安全
 
 -- 动态分区上限:本表跨 1632 dt(2021-10-28 ~ 2026-04-30)撞 hive 默认 1000/100。
 -- pernode 指 Spark task 节点(spark.sql.shuffle.partitions=200)不是物理 worker。
@@ -111,10 +110,10 @@ SELECT
     ods_dt                                           AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM (
         SELECT * FROM raw.raw_trd_card_group_order_info_his_o

+ 5 - 6
manual/backfill/20260507_ods_usr_app_base_user_inc_d_init.sql

@@ -1,10 +1,9 @@
 -- 作者:tianyu.chu
 -- 日期:2026-05-07
 -- 工单:(无)
--- 目的:ods_usr_app_base_user ods 初始化一次性灌入:raw 单表全部历史 dt → DATE(update_time) 归位 → ods 各 dt 分区
+-- 目的:ods_usr_app_base_user ods 初始化一次性灌入:raw 单表全部历史 dt → DATE(COALESCE(update_time, create_time)) 归位 → ods 各 dt 分区
 -- 状态:[待执行]
--- 备注:跑一次后由 jobs/ods/usr/ods_usr_app_base_user_inc_d.sql 接管日常增量;
---       update_time 为空的行落入 __HIVE_DEFAULT_PARTITION__(非阻塞,下游自行处理)
+-- 备注:跑一次后由 jobs/ods/usr/ods_usr_app_base_user_inc_d.sql 接管日常增量
 
 -- 动态分区上限:本表跨多年 dt 撞 hive 默认 1000/100。
 -- pernode 指 Spark task 节点(spark.sql.shuffle.partitions=200)不是物理 worker。
@@ -70,10 +69,10 @@ SELECT
     ods_dt                                          AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM raw.raw_usr_app_base_user_inc_d
 ) t

+ 5 - 6
manual/backfill/20260507_ods_usr_app_user_cert_info_inc_d_init.sql

@@ -1,10 +1,9 @@
 -- 作者:tianyu.chu
 -- 日期:2026-05-07
 -- 工单:(无)
--- 目的:ods_usr_app_user_cert_info ods 初始化一次性灌入:raw 单表全部历史 dt → DATE(update_time) 归位 → ods 各 dt 分区
+-- 目的:ods_usr_app_user_cert_info ods 初始化一次性灌入:raw 单表全部历史 dt → DATE(COALESCE(update_time, create_time)) 归位 → ods 各 dt 分区
 -- 状态:[待执行]
--- 备注:跑一次后由 jobs/ods/usr/ods_usr_app_user_cert_info_inc_d.sql 接管日常增量;
---       update_time 为空的行落入 __HIVE_DEFAULT_PARTITION__(非阻塞,下游自行处理)
+-- 备注:跑一次后由 jobs/ods/usr/ods_usr_app_user_cert_info_inc_d.sql 接管日常增量
 
 -- 动态分区上限:本表跨多年 dt 撞 hive 默认 1000/100。
 -- pernode 指 Spark task 节点(spark.sql.shuffle.partitions=200)不是物理 worker。
@@ -29,10 +28,10 @@ SELECT
     ods_dt                           AS dt
 FROM (
     SELECT *,
-        DATE_FORMAT(update_time, 'yyyyMMdd') AS ods_dt,
+        DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd') AS ods_dt,
         ROW_NUMBER() OVER (
-            PARTITION BY id, DATE_FORMAT(update_time, 'yyyyMMdd')
-            ORDER BY update_time DESC
+            PARTITION BY id, DATE_FORMAT(COALESCE(NULLIF(update_time, ''), create_time), 'yyyyMMdd')
+            ORDER BY COALESCE(NULLIF(update_time, ''), create_time) DESC
         ) AS rn
     FROM raw.raw_usr_app_user_cert_info_inc_d
 ) t