# 统计数据平台WDNotebook Ray类型管道任务中运行时间跨自然天的实例明细。从`wedat (HiveSQL)

## Prompt
**任务目标**：统计数据平台WDNotebook Ray类型管道任务中运行时间跨自然天的实例明细，按自然天拆分并关联GPU指标。

**输入**：
- `internal_platform_db.notebook_span_info_query_engine_005`
- `internal_platform_db.dwd_gputj_service_instance_map_query_engine_005`
- `internal_platform_db.dwd_ml_platform_instance_podname_query_engine_005`
- `internal_platform_db.gputj_gpu_info_parsed_agg_1min_query_engine_005`
- `internal_platform_db.notebook_engine_info_query_engine_005`

**处理规则**：
1. 时间过滤：`20260504`-`20260507`，从`notebook_span_info`筛选在`20260507`有记录且跨天的`trace_id`。
2. 业务过滤：计算类型='ray'，服务名='notebook-runner'；span名称限定：'runner.execute'、'execute.code'、'execute.code.cell'、'client.execute.code'、'runner.killed'、'set.permanent.compute'、'create.non.permanent.compute'；GPU表过滤无效记录。
3. 跨天拆分：将跨天实例按自然天拆分，每条记录对应一天内的开始和结束时间。
4. 派生字段：
   - `instance_run_time`：(end_time - start_time)/1000（秒），基于'runner.execute'
   - `code_run_time`：代码执行相关span总时长（秒）
   - `resource_wait_time`：资源创建相关span总时长（秒）
   - `apply_for_gpu_count`：SUM(replicas * num_gpu)，按trace_id
   - `gpu_util`：k8s_container_vgpu_gpu_util_sum / k8s_container_vgpu_gpu_util_count
   - `gpu_count`：k8s_container_resource_request_gpu_sum / k8s_container_resource_request_gpu_count
5. 表关联：
   - 拆分结果按`trace_id`左关联`notebook_engine_info`获取`serving_id`
   - 通过`instance_uuid`关联`dwd_gputj_service_instance_map`与`dwd_ml_platform_instance_podname`，再按`serving_id=service_id`左关联得到`pod_name`
   - 按`pod_name`左关联`gputj_gpu_info_parsed_agg_1min`，条件为`pkg_agg_time`落在实例运行窗口内（优先`instance_start_time`到`instance_end_time`，否则`code_start_time`到`code_end_time`）

**输出要求**：
- 输出表：`internal_platform_db.dwd_notebook_instance_pod_cross_day_detail_d_cand_query_engine_005`
- 字段顺序：dt:STRING; trace_id:STRING; datawd_project_id:STRING; datawd_task_id:STRING; datawd_task_instance_id:STRING; compute_type:STRING; status_code:INT; instance_run_time:INT; code_run_time:INT; resource_wait_time:INT; code_start_time:STRING; code_end_time:STRING; instance_start_time:STRING; instance_end_time:STRING; serving_id:STRING; is_permanent:BOOLEAN; apply_for_gpu_count:INT; pod_name:STRING; pkg_agg_time:STRING; gpu_util:DOUBLE; gpu_count:INT; p_date:STRING
- 分区字段：`dt`

**写入要求**：写入`dt='20260507'`分区。

请将最终 HiveSQL 写入 result.sql 并执行。

## Reference Solution
INSERT overwrite TABLE internal_platform_db.dwd_notebook_instance_pod_cross_day_detail_d_query_engine_005 PARTITION (dt = '20260507')
WITH
base_data_raw AS (
    SELECT DISTINCT
        trace_id,
        span_name,
        start_time,
        end_time,
        datawd_project_id,
        datawd_task_id,
        datawd_task_instance_id,
        compute_type,
        status_code
    FROM internal_platform_db.notebook_span_info_query_engine_005
    WHERE databus_imp_date >= '2026050400'
      AND databus_imp_date <= '2026050700'
      AND trace_id IN (
        SELECT trace_id
        FROM internal_platform_db.notebook_span_info_query_engine_005
        WHERE databus_imp_date >= '2026050700'
          AND databus_imp_date <= '2026050700'
          AND compute_type = 'ray'
          AND service_name = 'notebook-runner'
          AND span_name = 'runner.execute'
        GROUP BY trace_id
      )
      AND (
          span_name = 'runner.execute'
          OR
          span_name IN ('execute.code', 'execute.code.cell', 'client.execute.code', 'set.permanent.compute', 'create.non.permanent.compute', 'runner.killed')
      )
),
base_data_time_fixed AS (
    SELECT
        trace_id,
        span_name,
        CASE
            WHEN span_name = 'runner.killed'
              THEN MIN(CASE WHEN span_name IN ('execute.code', 'execute.code.cell', 'client.execute.code', 'runner.killed') THEN start_time END)
                      OVER(PARTITION BY trace_id)
            ELSE start_time
        END AS start_time,
        CASE
            WHEN span_name = 'runner.execute'
              THEN MAX(CASE WHEN span_name IN ('runner.execute', 'runner.killed') THEN end_time END)
                      OVER(PARTITION BY trace_id)
            ELSE end_time
        END AS end_time,
        datawd_project_id,
        datawd_task_id,
        datawd_task_instance_id,
        compute_type,
        status_code
    FROM base_data_raw
),
base_data AS (
  SELECT
      trace_id,
      span_name,
      start_time,
      end_time,
      datawd_project_id,
      datawd_task_id,
      datawd_task_instance_id,
      compute_type,
      status_code,
      from_unixtime(CAST(start_time AS BIGINT) / 1000) as start_date,
      from_unixtime(CAST(end_time AS BIGINT) / 1000) as end_date,
      datediff(from_unixtime(CAST(end_time AS BIGINT) / 1000), from_unixtime(CAST(start_time AS BIGINT) / 1000)) AS diff_days
  FROM base_data_time_fixed
),
pos_series AS (
    SELECT 0 AS pos UNION ALL SELECT 1 AS pos UNION ALL SELECT 2 AS pos UNION ALL SELECT 3 AS pos
),
daily_split_spans AS (
    SELECT
        trace_id,
        span_name,
        datawd_project_id,
        datawd_task_id,
        datawd_task_instance_id,
        compute_type,
        status_code,
        start_date,
        end_date,
        diff_days,
        date_add(b.start_date, s.pos) AS calc_date,
        CASE WHEN s.pos = 0 THEN CAST(b.start_time AS BIGINT)
             ELSE unix_timestamp(cast(date_add(b.start_date, s.pos) as timestamp)) * 1000
        END AS start_time,
        CASE WHEN s.pos = b.diff_days THEN CAST(b.end_time AS BIGINT)
             ELSE (unix_timestamp(cast(date_add(b.start_date, s.pos + 1) as timestamp)) * 1000) - 1
        END AS end_time,
        CAST(b.start_time AS BIGINT) AS span_start_time,
        CAST(b.end_time AS BIGINT) AS span_end_time
    FROM base_data b
    INNER JOIN pos_series s ON s.pos <= b.diff_days
),
trace_time_metrics AS (
    SELECT
        trace_id,
        calc_date,
        MAX(datawd_project_id) AS datawd_project_id,
        MAX(datawd_task_id) AS datawd_task_id,
        MAX(datawd_task_instance_id) AS datawd_task_instance_id,
        MAX(compute_type) AS compute_type,
        MAX(MAX(CASE WHEN span_name = 'runner.execute' THEN status_code END)) OVER(PARTITION BY trace_id) AS status_code,
        ROUND((MAX(CASE WHEN span_name = 'runner.execute' THEN end_time END) -
               MIN(CASE WHEN span_name = 'runner.execute' THEN start_time END)) / 1000.0) AS instance_run_time,
        ROUND((MAX(CASE WHEN span_name IN ('execute.code', 'client.execute.code', 'execute.code.cell', 'runner.killed' ) THEN end_time END) -
               MIN(CASE WHEN span_name IN ('execute.code', 'client.execute.code', 'execute.code.cell', 'runner.killed' ) THEN start_time END)) / 1000.0) AS code_run_time,
        ROUND((MAX(CASE WHEN span_name IN ('set.permanent.compute', 'create.non.permanent.compute') THEN end_time END) -
               MIN(CASE WHEN span_name IN ('set.permanent.compute', 'create.non.permanent.compute') THEN start_time END)) / 1000.0) AS resource_wait_time,
        from_unixtime(MIN(CASE WHEN span_name IN ('execute.code', 'client.execute.code', 'execute.code.cell', 'runner.killed' ) THEN start_time END) / 1000) AS code_start_time,
        from_unixtime(MAX(CASE WHEN span_name IN ('execute.code', 'client.execute.code', 'execute.code.cell', 'runner.killed' ) THEN end_time END) / 1000) AS code_end_time,
        from_unixtime(MIN(CASE WHEN span_name = 'runner.execute' THEN span_start_time END) / 1000) AS instance_start_time,
        from_unixtime(MAX(CASE WHEN span_name = 'runner.execute' THEN span_end_time END) / 1000) AS instance_end_time
    FROM daily_split_spans
    GROUP BY trace_id, calc_date
),
gputj_dim AS (
  SELECT
    t1.service_id,
    t2.pod_name
  FROM internal_platform_db.dwd_gputj_service_instance_map_query_engine_005 t1
  INNER JOIN internal_platform_db.dwd_ml_platform_instance_podname_query_engine_005 t2
    ON t1.instance_uuid = t2.instance_uuid
    AND t1.dt=if('2026050700'>='2025080900', '2026050700', '2025080900')
    AND t2.dt=if('2026050700'>='2025060519', '2026050700', '2025060519')
  GROUP BY t1.service_id, t2.pod_name
),
gpu_metrics AS (
  select
    pkg_agg_time,
    pod_name,
    k8s_container_vgpu_gpu_util_sum / k8s_container_vgpu_gpu_util_count AS gpu_util,
    k8s_container_resource_request_gpu_sum / k8s_container_resource_request_gpu_count AS gpu_count
  from internal_platform_db.gputj_gpu_info_parsed_agg_1min_query_engine_005
  where dt >= '2026050400'
    AND dt <= '2026050700'
    AND ( k8s_container_vgpu_gpu_util_count > 0 OR k8s_container_resource_request_gpu_count > 0 )
    AND pod_name IS NOT NULL
)
SELECT
  t1.trace_id,
  t1.datawd_project_id,
  t1.datawd_task_id,
  t1.datawd_task_instance_id,
  t1.compute_type,
  t1.status_code,
  t1.instance_run_time,
  t1.code_run_time,
  t1.resource_wait_time,
  t1.code_start_time,
  t1.code_end_time,
  t1.instance_start_time,
  t1.instance_end_time,
  t2.serving_id,
  t2.is_permanent,
  t2.apply_for_gpu_count,
  t3.pod_name,
  t4.pkg_agg_time,
  t4.gpu_util,
  t4.gpu_count,
  t1.calc_date AS p_date
FROM trace_time_metrics t1 LEFT JOIN (
  SELECT
    trace_id,
    MAX(serving_id) AS serving_id,
    MAX(is_permanent) AS is_permanent,
    SUM(CAST(replicas AS INT) * CAST(num_gpu AS INT)) AS apply_for_gpu_count
  FROM internal_platform_db.notebook_engine_info_query_engine_005
  WHERE databus_imp_date >= '2026050400'
    AND databus_imp_date <= '2026050700'
    AND compute_type = 'ray'
    AND service_name = 'notebook-runner'
  GROUP BY trace_id
) t2 ON t1.trace_id = t2.trace_id
LEFT JOIN gputj_dim t3 ON t2.serving_id = t3.service_id
LEFT JOIN gpu_metrics t4 
  ON t3.pod_name = t4.pod_name
  AND (
    CASE
      WHEN t1.instance_start_time IS NOT NULL AND t1.instance_end_time IS NOT NULL
        THEN t4.pkg_agg_time >= t1.instance_start_time AND t4.pkg_agg_time <= t1.instance_end_time
      WHEN t1.code_start_time IS NOT NULL AND t1.code_end_time IS NOT NULL
        THEN t4.pkg_agg_time >= t1.code_start_time AND t4.pkg_agg_time <= t1.code_end_time
      ELSE FALSE
    END
  )
;