# Notebook管道任务GPU利用率分钟级统计 (MySQL)

## Prompt
任务目标：按任务实例+分钟粒度统计 Notebook 管道任务的 GPU 利用率，区分实例整体利用率与代码运行时段利用率。

输入：
- 表：`internal_platform_db.dwd_notebook_instance_pod_detail_d_mysql_012`（Notebook 实例 Pod 明细表）

（表结构与字段含义请自行连接数据库查询确认）

- 过滤条件：`dt = '20260507'`

处理规则：
- 无 Join，单表处理
- 分组：按 `trace_id`, `p_date`, `pkg_agg_time` 分组
- 聚合口径：
  - `datawd_project_id` ~ `apply_for_gpu_count`：取 `MAX`
  - `code_gpu_count`：`SUM(IF(gpu_util IS NOT NULL, COALESCE(gpu_count, 0), gpu_count))`
  - `instance_gpu_util`：`AVG(CASE WHEN gpu_count IS NOT NULL THEN COALESCE(gpu_util, 0) ELSE NULL END)`（注意：当分组内所有行的 gpu_count 均为 NULL 时，CASE 表达式均返回 NULL，AVG 无有效行参与，结果为 NULL）
  - `code_gpu_util`：`AVG(CASE WHEN code_start_time IS NOT NULL AND code_end_time IS NOT NULL AND pkg_agg_time >= code_start_time AND pkg_agg_time <= code_end_time AND gpu_count IS NOT NULL THEN COALESCE(gpu_util, 0) ELSE NULL END)`
  - `is_code_running`：`MAX(CASE WHEN code_start_time IS NOT NULL AND code_end_time IS NOT NULL AND pkg_agg_time >= code_start_time AND pkg_agg_time <= code_end_time THEN 1 ELSE 0 END)`
  - `used_gpu_count`：`SUM(COALESCE(gpu_util, 0) * COALESCE(gpu_count, 0) / 100)`
  - `code_used_gpu_count`：`SUM(CASE WHEN code_start_time IS NOT NULL AND code_end_time IS NOT NULL AND pkg_agg_time >= code_start_time AND pkg_agg_time <= code_end_time THEN COALESCE(gpu_util, 0) * COALESCE(gpu_count, 0) / 100 ELSE 0 END)`

输出要求：
- 输出表：`internal_platform_db.dws_notebook_instance_execute_minute_stat_d_cand_mysql_012`
- 表注释：Notebook 管道任务实例分钟级运行统计信息
- 输出字段（按顺序）：`dt` VARCHAR(8)、`trace_id` VARCHAR(256)、`p_date` VARCHAR(256)、`pkg_agg_time` VARCHAR(256)、`datawd_project_id` VARCHAR(256)、`datawd_task_id` VARCHAR(256)、`datawd_task_instance_id` VARCHAR(256)、`compute_type` VARCHAR(256)、`status_code` INT、`instance_run_time` INT、`code_run_time` INT、`resource_wait_time` INT、`code_start_time` VARCHAR(256)、`code_end_time` VARCHAR(256)、`instance_start_time` VARCHAR(256)、`instance_end_time` VARCHAR(256)、`serving_id` VARCHAR(256)、`is_permanent` TINYINT(1)、`apply_for_gpu_count` INT、`code_gpu_count` INT、`instance_gpu_util` DOUBLE、`code_gpu_util` DOUBLE、`is_code_running` INT、`used_gpu_count` DOUBLE、`code_used_gpu_count` DOUBLE

写入要求：
- 使用 `INSERT INTO ... SELECT ...` 将结果写入输出表
- 若目标表不存在，先按 MySQL InnoDB 标准建表（`ENGINE=InnoDB DEFAULT CHARSET=utf8mb4`），再写入
- 请使用标准 MySQL 语法，不要使用 Hive/Spark SQL 方言（如不要使用 `INSERT OVERWRITE`、不要使用 `STORED AS ORC`、不要使用分区表语法）

**环境与执行说明**：
- 你的最终产出必须写入文件 `/tmp_workspace/result.py`，不能写 result.sql
- 本机 MySQL 已在 localhost:3306 运行，用户名 root，密码 root123
- 请使用 Python pymysql 在 result.py 中执行 SQL（不要用 mysql 命令行）
- 脚本需要包含完整的建表（如目标表不存在）+ 写入数据的逻辑
- 写出 result.py 后，你必须自己执行 `python3 /tmp_workspace/result.py` 验证它能成功运行并产出正确数据

## Reference Solution
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
mysql_012 ground truth: Notebook 管道任务实例分钟级 GPU 利用率统计

Task:
  Filter input table WHERE dt = '20260507',
  group by trace_id, p_date, pkg_agg_time,
  aggregate MAX/SUM/AVG per the spec,
  write to output table.
"""
import pymysql
import sys

DB_NAME = "internal_platform_db"
INPUT_TABLE = "dwd_notebook_instance_pod_detail_d_mysql_012"
OUTPUT_TABLE = "dws_notebook_instance_execute_minute_stat_d_cand_mysql_012"

MYSQL_CONFIG = {
    "host": "localhost",
    "port": 3306,
    "user": "root",
    "password": "root123",
    "charset": "utf8mb4",
}

gt_sql = f"""
INSERT INTO {DB_NAME}.{OUTPUT_TABLE}
    (dt, trace_id, p_date, pkg_agg_time, datawd_project_id, datawd_task_id,
     datawd_task_instance_id, compute_type, status_code, instance_run_time,
     code_run_time, resource_wait_time, code_start_time, code_end_time,
     instance_start_time, instance_end_time, serving_id, is_permanent,
     apply_for_gpu_count, code_gpu_count, instance_gpu_util, code_gpu_util,
     is_code_running, used_gpu_count, code_used_gpu_count)
SELECT
    '20260507' AS dt,
    trace_id,
    p_date,
    pkg_agg_time,
    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(status_code) AS status_code,
    MAX(instance_run_time) AS instance_run_time,
    MAX(code_run_time) AS code_run_time,
    MAX(resource_wait_time) AS resource_wait_time,
    MAX(code_start_time) AS code_start_time,
    MAX(code_end_time) AS code_end_time,
    MAX(instance_start_time) AS instance_start_time,
    MAX(instance_end_time) AS instance_end_time,
    MAX(serving_id) AS serving_id,
    MAX(is_permanent) AS is_permanent,
    MAX(apply_for_gpu_count) AS apply_for_gpu_count,
    SUM(IF(gpu_util IS NOT NULL, COALESCE(gpu_count, 0), gpu_count)) AS code_gpu_count,
    AVG(CASE WHEN gpu_count IS NOT NULL THEN COALESCE(gpu_util, 0) ELSE NULL END) AS instance_gpu_util,
    AVG(
        CASE
          WHEN code_start_time IS NOT NULL AND code_end_time IS NOT NULL
            AND pkg_agg_time >= code_start_time AND pkg_agg_time <= code_end_time
            AND gpu_count IS NOT NULL
          THEN COALESCE(gpu_util, 0)
          ELSE NULL
        END
    ) AS code_gpu_util,
    MAX(
      CASE
        WHEN code_start_time IS NOT NULL
          AND code_end_time IS NOT NULL
          AND pkg_agg_time >= code_start_time
          AND pkg_agg_time <= code_end_time
        THEN 1 ELSE 0
      END
    ) AS is_code_running,
    SUM(COALESCE(gpu_util, 0) * COALESCE(gpu_count, 0) / 100) AS used_gpu_count,
    SUM(
        CASE
          WHEN code_start_time IS NOT NULL AND code_end_time IS NOT NULL
            AND pkg_agg_time >= code_start_time AND pkg_agg_time <= code_end_time
          THEN COALESCE(gpu_util, 0) * COALESCE(gpu_count, 0) / 100
          ELSE 0
        END
    ) AS code_used_gpu_count
FROM {DB_NAME}.{INPUT_TABLE}
WHERE dt = '20260507'
GROUP BY
    trace_id,
    p_date,
    pkg_agg_time
"""


def main():
    conn = pymysql.connect(**MYSQL_CONFIG)

    try:
        with conn.cursor() as cur:
            # Ensure output table exists
            cur.execute(f"""
                CREATE TABLE IF NOT EXISTS {DB_NAME}.{OUTPUT_TABLE} (
                    dt                     VARCHAR(8)    COMMENT '天分区',
                    trace_id               VARCHAR(256)  COMMENT '',
                    p_date                 VARCHAR(256)  COMMENT '',
                    pkg_agg_time           VARCHAR(256)  COMMENT '分钟级时间戳',
                    datawd_project_id       VARCHAR(256)  COMMENT '',
                    datawd_task_id         VARCHAR(256)  COMMENT '',
                    datawd_task_instance_id VARCHAR(256) COMMENT '',
                    compute_type           VARCHAR(256)  COMMENT '',
                    status_code            INT           COMMENT '',
                    instance_run_time      INT           COMMENT '',
                    code_run_time          INT           COMMENT '',
                    resource_wait_time     INT           COMMENT '',
                    code_start_time        VARCHAR(256)  COMMENT '',
                    code_end_time          VARCHAR(256)  COMMENT '',
                    instance_start_time    VARCHAR(256)  COMMENT '',
                    instance_end_time      VARCHAR(256)  COMMENT '',
                    serving_id             VARCHAR(256)  COMMENT '',
                    is_permanent           TINYINT(1)    COMMENT '布尔型',
                    apply_for_gpu_count    INT           COMMENT '',
                    code_gpu_count         INT           COMMENT '',
                    instance_gpu_util      DOUBLE        COMMENT '',
                    code_gpu_util          DOUBLE        COMMENT '',
                    is_code_running        INT           COMMENT '',
                    used_gpu_count         DOUBLE        COMMENT '',
                    code_used_gpu_count    DOUBLE        COMMENT ''
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
                  COMMENT='Notebook 管道任务实例分钟级运行统计信息'
            """)

            # Truncate + insert
            cur.execute(f"TRUNCATE TABLE {DB_NAME}.{OUTPUT_TABLE}")
            cur.execute(gt_sql)

        conn.commit()
        print("mysql_012 ground_truth done: rows written to output table")
    except Exception as e:
        print(f"ground_truth error: {e}", file=sys.stderr)
        conn.rollback()
        sys.exit(1)
    finally:
        conn.close()


if __name__ == "__main__":
    main()