lunar_same_period_demands.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. """去年同期阴历策略 ODPS 查询。"""
  2. from app.odps.client import get_odps_client
  3. from app.strategies.odps._date_utils import partition_yyyymmdd, today_shanghai_date
  4. from app.strategies.odps._utils import normalize_scalar, parse_video_list
  5. def build_lunar_same_period_sql(
  6. *,
  7. bizdate: str,
  8. period_days: int,
  9. view_pv_count: int,
  10. min_contribution_score: float,
  11. rov_avg: float,
  12. ) -> str:
  13. if period_days < 1:
  14. raise ValueError("period_days 须 >= 1")
  15. days_after = period_days - 1
  16. return f"""
  17. SET odps.sql.type.system.odps2 = true
  18. ;
  19. WITH base_date AS (
  20. SELECT
  21. lunar_to_solar(
  22. lunar_add(
  23. loghubods.solar_to_lunar('{bizdate}', 'yyyyMMdd'),
  24. -1,
  25. 'Y'
  26. )
  27. ) AS start_date
  28. ),
  29. date_params AS (
  30. SELECT
  31. start_date,
  32. DATE_FORMAT(
  33. CAST(DATE_ADD(TO_DATE(start_date, 'yyyyMMdd'), {int(days_after)}) AS TIMESTAMP),
  34. 'yyyyMMdd'
  35. ) AS end_date
  36. FROM base_date
  37. ),
  38. cleaned_video_metrics AS (
  39. SELECT
  40. CAST(d.视频id AS STRING) AS vid,
  41. d.rov_t0
  42. FROM loghubods.video_dimension_detail_add_column d
  43. WHERE d.dt >= (SELECT start_date FROM date_params)
  44. AND d.dt <= (SELECT end_date FROM date_params)
  45. AND COALESCE(d.`当日分发曝光pv`, 0) >= {int(view_pv_count)}
  46. ),
  47. video_avg_metrics AS (
  48. SELECT
  49. vid,
  50. AVG(CASE WHEN rov_t0 = 0 THEN NULL ELSE rov_t0 END) AS vid_avg_rov
  51. FROM cleaned_video_metrics
  52. GROUP BY vid
  53. ),
  54. tag_vid_dedup AS (
  55. SELECT DISTINCT
  56. CAST(vid AS STRING) AS vid,
  57. 原始元素,
  58. 原始元素描述,
  59. 点类型,
  60. 元素维度,
  61. 短语,
  62. 选题,
  63. `extend`
  64. FROM loghubods.dwd_topic_decode_result_detail_di
  65. WHERE dt = MAX_PT('loghubods.dwd_topic_decode_result_detail_di')
  66. AND TRIM(原始元素) <> ''
  67. AND 原始元素 IS NOT NULL
  68. AND 元素维度 = '实质'
  69. AND 贡献分 >= {float(min_contribution_score)}
  70. )
  71. SELECT
  72. '去年同期阴历' AS strategy,
  73. md5(CONCAT('去年同期阴历', t1.原始元素, '{bizdate}')) AS demand_id,
  74. t1.原始元素 AS demand_name,
  75. COALESCE(ROUND(AVG(t2.vid_avg_rov), 6), 0) AS weight,
  76. '特征点' AS type,
  77. COUNT(DISTINCT t1.vid) AS video_count,
  78. COLLECT_SET(t1.vid) AS video_list,
  79. '{{}}' AS extend
  80. FROM tag_vid_dedup t1
  81. LEFT JOIN video_avg_metrics t2
  82. ON t1.vid = t2.vid
  83. GROUP BY t1.原始元素
  84. HAVING COALESCE(ROUND(AVG(t2.vid_avg_rov), 6), 0) >= {float(rov_avg)}
  85. ORDER BY weight DESC
  86. """
  87. def query_lunar_same_period_demands(
  88. *,
  89. bizdate: str | None = None,
  90. period_days: int = 7,
  91. view_pv_count: int,
  92. min_contribution_score: float,
  93. rov_avg: float,
  94. ) -> list[dict[str, object]]:
  95. if bizdate is None:
  96. bizdate = partition_yyyymmdd(today_shanghai_date())
  97. sql = build_lunar_same_period_sql(
  98. bizdate=bizdate,
  99. period_days=period_days,
  100. view_pv_count=view_pv_count,
  101. min_contribution_score=min_contribution_score,
  102. rov_avg=rov_avg,
  103. )
  104. odps_client = get_odps_client()
  105. instance = odps_client.execute_sql(
  106. sql,
  107. hints={
  108. "odps.sql.submit.mode": "script",
  109. "odps.sql.decimal.odps2": "true",
  110. },
  111. )
  112. rows: list[dict[str, object]] = []
  113. with instance.open_reader(tunnel=True) as reader:
  114. for record in reader:
  115. rows.append(
  116. {
  117. "strategy": record["strategy"],
  118. "demand_id": record["demand_id"],
  119. "demand_name": record["demand_name"],
  120. "weight": normalize_scalar(record["weight"]),
  121. "type": record["type"],
  122. "video_count": record["video_count"],
  123. "video_list": parse_video_list(record["video_list"]),
  124. "extend": record["extend"],
  125. }
  126. )
  127. return rows