ods_trd_card_group_info_ful_d.sql 5.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. -- 作者:tianyu.chu
  2. -- 日期:2026-07-17
  3. -- 工单:(无)
  4. -- 目的:拼团全量最新态日常 merge —— full dt=${dt} = 昨日全量中今天没变的 + 今日增量
  5. -- 状态:[草案]
  6. -- 备注:sched=T,${dt}=业务日 T-1、${pdt}=T-2(即前一天的 full)。
  7. --
  8. -- **反连接而非窗口函数**:今天的全量 = 「昨日全量 LEFT ANTI JOIN 今日增量 id」+「今日增量」。
  9. -- 右侧只有当日变更的 id(千级),Spark 会 broadcast,全量表只扫不 shuffle、也不排序。
  10. -- 若改用 ROW_NUMBER() OVER (PARTITION BY id) 套在 union 上,等于每天把全量按 id 全shuffle+排序一遍,
  11. -- 增量才几千行却要搬动全表,merge 的意义就没了。
  12. -- 正确性:ODS inc 单个 dt 分区内一个 id 只有一行(已按 (id, ods_dt) 去重),且 inc dt=${dt}
  13. -- 意味着该记录最后变更就在当天、必然比昨日全量那版新 —— 故「变了的取 inc、没变的留昨日」
  14. -- 与「取 max(update_time)」等价。
  15. -- 注:LEFT ANTI JOIN 是 Spark SQL 语法(Hive 2.1 不支持),本 SQL 走 spark-sql-starter,无碍。
  16. --
  17. -- **静态分区写入**(PARTITION(dt='${dt}'))是硬要求:本 SQL 读 full dt=${pdt} 又写 full,
  18. -- 若用动态分区(PARTITION(dt)),输出路径=表根目录、与读的分区路径重叠,Spark 会报
  19. -- "Cannot overwrite a path that is also being read from"。静态分区的输出是具体分区目录,不重叠。
  20. -- 起点由 manual/backfill/20260717_..._ful_d_seed.sql 一次性 seed;断链需重新 seed。
  21. -- 历史多版本在 inc 表(拉链底座),本表只保当前态。lock 是保留字,SELECT 里必须带反引号。
  22. --
  23. -- **分区保留 2 天**(只留 ${dt} 与 ${pdt}):文末 ALTER 精确 drop ${rdt}(=${dt}-2,即 T-3),
  24. -- 每天正好掉一个。用精确分区值而非 dt < 'x'——Spark SQL 的 DROP PARTITION 只接受 col=value,
  25. -- 比较式是 Hive 语法、Spark 解析不了。DS 需额外传参 rdt=$[yyyyMMdd-3];手动跑加 -p rdt=<T-3>。
  26. -- 代价:漏跑一天则那天本该掉的分区不会被补 drop,需手工清;断链重新 seed 即可。
  27. INSERT OVERWRITE TABLE ods.ods_trd_card_group_info_ful_d PARTITION (dt='${dt}')
  28. -- 昨日全量里今天没变的
  29. SELECT
  30. id, merchant_id, appid, name, code,
  31. status, specs, type, random_type, total_price,
  32. copies, unit_price, sold_copies, release_time, cycle,
  33. show_applet, title, msg, remark, create_time,
  34. update_by, update_time, order_quota_min, order_quota_max, user_quota_max,
  35. start_time, marketing_info, reviewmsg, `lock`, commission_rate,
  36. year, sport, manufacturer, sets, act,
  37. config, info_config, total_num, banner_end_time, add_banner,
  38. finished_time, display_name, group_sets_no, close_payment_time, confirm_send_time,
  39. close_payment_status, open_card, close_payment_record, group_full_time, live_create_time,
  40. live_start_time, live_end_time, report_start_time, report_end_time, report_review_num,
  41. report_review_first_time, report_review_end_time, review_hold_time, review_approval_time, review_num,
  42. config_json, free_flag, mer_name, change_type, act_price,
  43. act_config_json, real_sold_num, weight, hot_type, team_first,
  44. prop1, prop2, prop3, point_rate, point_max,
  45. point_min, list_id, list_code, mix_copies, sub_type,
  46. act_point_type, payment_method, payment_total_price, payment_commission, payment_finished_price,
  47. payment_remain_price, payment_online_price, exclusive, has_bg, merchant_sort,
  48. del_flg, del_time, review_account, act_id, sold_end_time,
  49. panini_list_id, hot_type_config, goods_type, report_flag, use_coupon,
  50. user_level, custom, gift_card_id, group_show_name, min_card_num,
  51. act_type, waring_type, compensation_status, point_type, first_act_config,
  52. gift_config, version, extra_prop, use_member_discount, merchant_open,
  53. is_deleted
  54. FROM (SELECT * FROM ods.ods_trd_card_group_info_ful_d WHERE dt = '${pdt}') f
  55. LEFT ANTI JOIN (
  56. SELECT id FROM ods.ods_trd_card_group_info_inc_d WHERE dt = '${dt}'
  57. ) i ON f.id = i.id
  58. UNION ALL
  59. -- 今日变了的(含今日新建)
  60. SELECT
  61. id, merchant_id, appid, name, code,
  62. status, specs, type, random_type, total_price,
  63. copies, unit_price, sold_copies, release_time, cycle,
  64. show_applet, title, msg, remark, create_time,
  65. update_by, update_time, order_quota_min, order_quota_max, user_quota_max,
  66. start_time, marketing_info, reviewmsg, `lock`, commission_rate,
  67. year, sport, manufacturer, sets, act,
  68. config, info_config, total_num, banner_end_time, add_banner,
  69. finished_time, display_name, group_sets_no, close_payment_time, confirm_send_time,
  70. close_payment_status, open_card, close_payment_record, group_full_time, live_create_time,
  71. live_start_time, live_end_time, report_start_time, report_end_time, report_review_num,
  72. report_review_first_time, report_review_end_time, review_hold_time, review_approval_time, review_num,
  73. config_json, free_flag, mer_name, change_type, act_price,
  74. act_config_json, real_sold_num, weight, hot_type, team_first,
  75. prop1, prop2, prop3, point_rate, point_max,
  76. point_min, list_id, list_code, mix_copies, sub_type,
  77. act_point_type, payment_method, payment_total_price, payment_commission, payment_finished_price,
  78. payment_remain_price, payment_online_price, exclusive, has_bg, merchant_sort,
  79. del_flg, del_time, review_account, act_id, sold_end_time,
  80. panini_list_id, hot_type_config, goods_type, report_flag, use_coupon,
  81. user_level, custom, gift_card_id, group_show_name, min_card_num,
  82. act_type, waring_type, compensation_status, point_type, first_act_config,
  83. gift_config, version, extra_prop, use_member_discount, merchant_open,
  84. is_deleted
  85. FROM ods.ods_trd_card_group_info_inc_d
  86. WHERE dt = '${dt}';
  87. -- 保留 2 天:drop 掉 ${dt}-2(T-3)这一个分区
  88. ALTER TABLE ods.ods_trd_card_group_info_ful_d DROP IF EXISTS PARTITION (dt='${rdt}');