# 从输入表中筛选状态为 killed 的 Notebook runner trace 数据，按天拆分后 (HiveSQL)

## Prompt
1) 任务目标
产出 killed 状态的 Notebook 实例 Pod 运行明细宽表。

2) 输入
- internal_platform_db.gputj_gpu_info_parsed_agg_1min_query_engine_024
- internal_platform_db.notebook_span_info_query_engine_024
- internal_platform_db.dwd_gputj_service_instance_map_query_engine_024
- internal_platform_db.dwd_ml_platform_instance_podname_query_engine_024
- internal_platform_db.notebook_engine_info_query_engine_024

3) 处理规则
- 过滤条件：筛选 Notebook runner trace 中状态为 killed 的记录
- 时间处理：对 runner trace 数据按天拆分
- 关联顺序：runner trace → 服务实例 → Pod → GPU 聚合 → engine 信息
- 关联方式：按各表对应键字段进行左连接

4) 输出要求
- 输出表：internal_platform_db.dwd_notebook_killed_instance_pod_detail_d_cand_query_engine_024
- 包含 runner trace、服务实例、Pod、GPU、engine 等关联后的明细字段
- 去重规则：按主键去重（若存在）

5) 写入要求
- 写入模式：INSERT OVERWRITE
- 分区字段：按天分区（如有）

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

## Reference Solution
INSERT OVERWRITE TABLE internal_platform_db.dwd_notebook_killed_instance_pod_detail_d_query_engine_024 PARTITION (dt = '20260507')
WITH base_trace AS (
    SELECT trace_id
    FROM internal_platform_db.notebook_span_info_query_engine_024
    WHERE databus_imp_date >= '2026050700'
      AND databus_imp_date <= '2026050700'
      AND compute_type = 'ray'
      AND service_name = 'notebook-runner'
      AND span_name IN ('runner.execute', 'runner.killed')
    GROUP BY trace_id
    HAVING
        COUNT(CASE WHEN span_name = 'runner.killed' THEN 1 END) > 0
        AND
        COUNT(CASE WHEN span_name = 'runner.execute' THEN 1 END) = 0
),
combined_spans 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 internal_platform_db.notebook_span_info_query_engine_024
  WHERE databus_imp_date >= '2026050400'
    AND databus_imp_date <= '2026050700'
    AND trace_id IN (SELECT trace_id FROM base_trace)
    AND span_name IN ('runner.killed', 'runner.start', 'execute.code', 'execute.code.cell', 'client.execute.code', 'set.permanent.compute', 'create.non.permanent.compute')

  UNION ALL

  SELECT
      trace_id,
      'runner.execute' AS span_name,
      MAX(CASE WHEN span_name = 'runner.start' THEN start_time END) AS start_time,
      MAX(CASE WHEN span_name = 'runner.killed' THEN end_time END) AS end_time,
      MAX(CASE WHEN span_name = 'runner.killed' THEN datawd_project_id END) AS datawd_project_id,
      MAX(CASE WHEN span_name = 'runner.killed' THEN datawd_task_id END) AS datawd_task_id,
      MAX(CASE WHEN span_name = 'runner.killed' THEN datawd_task_instance_id END) AS datawd_task_instance_id,
      MAX(CASE WHEN span_name = 'runner.killed' THEN compute_type END) AS compute_type,
      2 AS status_code
  FROM internal_platform_db.notebook_span_info_query_engine_024
  WHERE databus_imp_date >= '2026050400'
    AND databus_imp_date <= '2026050700'
    AND trace_id IN (SELECT trace_id FROM base_trace)
    AND span_name IN ('runner.start', 'runner.killed')
  GROUP BY trace_id
),
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,
      end_time,
      datawd_project_id,
      datawd_task_id,
      datawd_task_instance_id,
      compute_type,
      status_code
  FROM combined_spans
),
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 b.start_time
             ELSE CAST(unix_timestamp(CAST(date_add(b.start_date, s.pos) AS TIMESTAMP)) * 1000 AS STRING)
        END AS start_time,
        CASE WHEN s.pos = b.diff_days THEN b.end_time
             ELSE CAST((unix_timestamp(CAST(date_add(b.start_date, s.pos + 1) AS TIMESTAMP)) * 1000) - 1 AS STRING)
        END AS end_time,
        b.start_time AS span_start_time,
        b.end_time 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 CAST(end_time AS BIGINT) END) -
               MIN(CASE WHEN span_name = 'runner.execute' THEN CAST(start_time AS BIGINT) 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 CAST(end_time AS BIGINT) END) -
               MIN(CASE WHEN span_name IN ('execute.code', 'client.execute.code', 'execute.code.cell', 'runner.killed' ) THEN CAST(start_time AS BIGINT) END)) / 1000.0) AS code_run_time,
        ROUND((MAX(CASE WHEN span_name IN ('set.permanent.compute', 'create.non.permanent.compute') THEN CAST(end_time AS BIGINT) END) -
               MIN(CASE WHEN span_name IN ('set.permanent.compute', 'create.non.permanent.compute') THEN CAST(start_time AS BIGINT) 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 CAST(start_time AS BIGINT) 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 CAST(end_time AS BIGINT) END) / 1000) AS code_end_time,
        from_unixtime(MIN(CASE WHEN span_name = 'runner.execute' THEN CAST(span_start_time AS BIGINT) END) / 1000) AS instance_start_time,
        from_unixtime(MAX(CASE WHEN span_name = 'runner.execute' THEN CAST(span_end_time AS BIGINT) 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_024 t1
  INNER JOIN internal_platform_db.dwd_ml_platform_instance_podname_query_engine_024 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_024
  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,
  CAST(t1.instance_run_time AS INT),
  CAST(t1.code_run_time AS INT),
  CAST(t1.resource_wait_time AS INT),
  t1.code_start_time,
  t1.code_end_time,
  t1.instance_start_time,
  t1.instance_end_time,
  t2.serving_id,
  CAST(t2.is_permanent AS BOOLEAN),
  CAST(t2.apply_for_gpu_count AS INT),
  t3.pod_name,
  t4.pkg_agg_time,
  t4.gpu_util,
  CAST(t4.gpu_count AS INT),
  CAST(t1.calc_date AS STRING) 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 DOUBLE) * CAST(num_gpu AS DOUBLE)) AS apply_for_gpu_count
  FROM internal_platform_db.notebook_engine_info_query_engine_024
  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 = CAST(t3.service_id AS STRING)
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
  )
;