# 传感器事件宽表关联用户组帖子分类圈组维度 (MySQL)

## Prompt
我需要你生成一段 MySQL 代码，将传感器事件数据关联用户组、帖子、分类和圈组维度，生成帖子事件明细宽表。

**业务背景与目标**：传感器事件明细表记录了用户在社区中的各种行为（浏览帖子、点赞、收藏、评论等）。需要将事件数据与圈组成员关系、帖子信息、分类信息和圈组信息进行关联，生成一张帖子事件明细宽表，供下游分析使用。

**输入表（全名 + 简要描述）**：

- `internal_platform_db.dwd_knowledge_base_sensors_event_di_mysql_019`（传感器事件明细表）
- `internal_platform_db.dwv_knowledge_base_groups_users_df_mysql_019`（圈组成员关系表）
- `internal_platform_db.dwv_kb_posts_df_mysql_019`（帖子信息表）
- `internal_platform_db.dwv_kb_categories_df_mysql_019`（分类信息表）
- `internal_platform_db.dwv_knowledge_base_groups_df_mysql_019`（圈组信息表）

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

**处理规则**：

1. 主表 t1 从 `dwd_knowledge_base_sensors_event_di_mysql_019` 筛选：
   - `concat(year,month,day)='20260608'`
   - `lower(event) in ('postdetailview','postdigg','postbooknowledge_baseark','postrecommend','commentsend','postcomment')`
   - `(group_id is not null or show_groups is not null)`
   - `post_id is not null and post_id != ''`
   - 派生字段：
     - `time as event_time`
     - `pc_or_mobile = if(lower(platform_type) in ('ios','android','h5'), 'mobile', 'pc')`
     - `group_id = ifnull(show_groups, group_id)`

2. 左关联 t2（来自 `dwv_knowledge_base_groups_users_df_mysql_019`）：
   - 筛选条件：`concat(year,month,day)='20260608'` 且 `enabled=1`
   - 关联条件：`t1.distinct_id = t2.nick` 且 `t1.group_id = t2.group_id`
   - 派生字段：`is_group_member = IF(t2.nick is null, 0, 1)`

3. 左关联 t3（`dwv_kb_posts_df_mysql_019` 左关联 `dwv_kb_categories_df_mysql_019`）：
   - t3 内部 tt1 来自 `dwv_kb_posts_df_mysql_019`，分区 `concat(year,month,day)='20260608'`
   - t3 内部 tt2 来自 `dwv_kb_categories_df_mysql_019`，分区 `concat(year,month,day)='20260608'`
   - tt1 和 tt2 通过 `tt1.category_id = tt2.id` 关联
   - t3 与 t1 通过 `post_id = id` 关联
   - 输出字段：`post_authorship`（来自 authorship）, `posts_category_id`（来自 category_id）, `posts_category_name`（来自 category_name 即 tt2.name）

4. 左关联 t4（来自 `dwv_knowledge_base_groups_df_mysql_019`）：
   - 筛选条件：`concat(year,month,day)='20260608'`
   - 关联条件：`t1.group_id = t4.code`
   - 输出字段：`t4_group_id`（来自 t4.id）

5. 最终 `group_id` 字段取值：`ifnull(t4_group_id, group_id)`

**输出要求**：
- 目标表：`internal_platform_db.dwd_knowledge_base_k_bar_posts_event_di_cand_mysql_019`
- 输出字段顺序：`event`, `distinct_id`, `appname`, `user_id`, `event_time`, `receive_time`, `os`, `track_signup_original_id`, `author_nick`, `platform_type`, `target_type`, `target_id`, `ip`, `post_id`, `show_groups`, `group_id`（解析后）, `source_page`, `source_module`, `operation_type`, `pc_or_mobile`, `is_group_member`, `post_authorship`, `posts_category_id`, `posts_category_name`
- 如果目标表不存在，请先按 MySQL InnoDB 标准建表，再写入数据
- 请使用标准 MySQL 语法，不要使用 Hive/Spark SQL 方言（如 `INSERT OVERWRITE`、`STORED AS ORC`、`PARTITIONED BY` 等）

**环境与执行说明**：
- 你的最终产出必须写入文件 `/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_019 ground truth: 传感器事件宽表关联用户组帖子分类圈组维度

Task:
  Join sensor events with groups_users, posts+categories, and groups
  to produce a posts event detail wide table.
"""
import pymysql
import sys

DB_NAME = "internal_platform_db"
INPUT_TABLE_SENSORS = "dwd_knowledge_base_sensors_event_di_mysql_019"
INPUT_TABLE_GROUPS_USERS = "dwv_knowledge_base_groups_users_df_mysql_019"
INPUT_TABLE_POSTS = "dwv_kb_posts_df_mysql_019"
INPUT_TABLE_CADEPT_TORIES = "dwv_kb_categories_df_mysql_019"
INPUT_TABLE_GROUPS = "dwv_knowledge_base_groups_df_mysql_019"
OUTPUT_TABLE = "dwd_knowledge_base_k_bar_posts_event_di_cand_mysql_019"

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

gt_sql = f"""
INSERT INTO {DB_NAME}.{OUTPUT_TABLE}
    (event, distinct_id, appname, user_id, event_time, receive_time, os,
     track_signup_original_id, author_nick, platform_type, target_type, target_id,
     ip, post_id, show_groups, group_id, source_page, source_module, operation_type,
     pc_or_mobile, is_group_member, post_authorship, posts_category_id, posts_category_name,
     year, month, day)
SELECT
    event,
    distinct_id,
    appname,
    user_id,
    event_time,
    receive_time,
    os,
    track_signup_original_id,
    author_nick,
    platform_type,
    target_type,
    target_id,
    ip,
    post_id,
    show_groups,
    IFNULL(t4_group_id, group_id) AS group_id,
    source_page,
    source_module,
    operation_type,
    pc_or_mobile,
    IF(t2.nick IS NULL, 0, 1) AS is_group_member,
    post_authorship,
    posts_category_id,
    posts_category_name,
    '2026' AS year,
    '06' AS month,
    '08' AS day
FROM (
    SELECT
        event,
        distinct_id,
        appname,
        user_id,
        time AS event_time,
        receive_time,
        os,
        track_signup_original_id,
        author_nick,
        platform_type,
        target_type,
        target_id,
        ip,
        post_id,
        show_groups,
        IFNULL(show_groups, group_id) AS group_id,
        source_page,
        source_module,
        operation_type,
        IF(LOWER(platform_type) IN ('ios', 'android', 'h5'), 'mobile', 'pc') AS pc_or_mobile
    FROM
        {DB_NAME}.{INPUT_TABLE_SENSORS}
    WHERE
        CONCAT(year, month, day) = '20260608'
        AND LOWER(event) IN ('postdetailview', 'postdigg', 'postbooknowledge_baseark',
                             'postrecommend', 'commentsend', 'postcomment')
        AND (group_id IS NOT NULL OR show_groups IS NOT NULL)
        AND post_id IS NOT NULL AND post_id != ''
) t1
LEFT JOIN (
    SELECT
        nick,
        group_id AS t2_group_id
    FROM
        {DB_NAME}.{INPUT_TABLE_GROUPS_USERS}
    WHERE
        CONCAT(year, month, day) = '20260608'
        AND enabled = 1
) t2
ON t1.distinct_id = t2.nick AND t1.group_id COLLATE utf8mb4_unicode_ci = CONVERT(t2.t2_group_id, CHAR) COLLATE utf8mb4_unicode_ci
LEFT JOIN (
    SELECT
        id AS t3_id,
        authorship AS post_authorship,
        category_id AS posts_category_id,
        category_name AS posts_category_name
    FROM (
        SELECT
            id,
            authorship,
            category_id
        FROM
            {DB_NAME}.{INPUT_TABLE_POSTS}
        WHERE
            CONCAT(year, month, day) = '20260608'
    ) tt1
    LEFT JOIN (
        SELECT
            id AS tt2_id,
            name AS category_name
        FROM
            {DB_NAME}.{INPUT_TABLE_CADEPT_TORIES}
        WHERE
            CONCAT(year, month, day) = '20260608'
    ) tt2
    ON tt1.category_id = tt2.tt2_id
) t3
ON t1.post_id COLLATE utf8mb4_unicode_ci = CONVERT(t3.t3_id, CHAR) COLLATE utf8mb4_unicode_ci
LEFT JOIN (
    SELECT
        id AS t4_group_id,
        code AS t4_group_code
    FROM
        {DB_NAME}.{INPUT_TABLE_GROUPS}
    WHERE
        CONCAT(year, month, day) = '20260608'
) t4
ON t1.group_id = t4.t4_group_code
"""


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} (
                    event                    VARCHAR(256) DEFAULT NULL,
                    distinct_id              VARCHAR(256) DEFAULT NULL,
                    appname                  VARCHAR(256) DEFAULT NULL,
                    user_id                  VARCHAR(256) DEFAULT NULL,
                    event_time               VARCHAR(256) DEFAULT NULL,
                    receive_time             VARCHAR(256) DEFAULT NULL,
                    os                       VARCHAR(256) DEFAULT NULL,
                    track_signup_original_id VARCHAR(256) DEFAULT NULL,
                    author_nick              VARCHAR(256) DEFAULT NULL,
                    platform_type            VARCHAR(256) DEFAULT NULL,
                    target_type              VARCHAR(256) DEFAULT NULL,
                    target_id                VARCHAR(256) DEFAULT NULL,
                    ip                       VARCHAR(256) DEFAULT NULL,
                    post_id                  VARCHAR(256) DEFAULT NULL,
                    show_groups              VARCHAR(256) DEFAULT NULL,
                    group_id                 VARCHAR(256) DEFAULT NULL,
                    source_page              VARCHAR(256) DEFAULT NULL,
                    source_module            VARCHAR(256) DEFAULT NULL,
                    operation_type           VARCHAR(256) DEFAULT NULL,
                    pc_or_mobile             VARCHAR(256) DEFAULT NULL,
                    is_group_member          INT          DEFAULT NULL,
                    post_authorship          VARCHAR(256) DEFAULT NULL,
                    posts_category_id        BIGINT       DEFAULT NULL,
                    posts_category_name      VARCHAR(256) DEFAULT NULL,
                    year                     VARCHAR(256) DEFAULT NULL,
                    month                    VARCHAR(256) DEFAULT NULL,
                    day                      VARCHAR(256) DEFAULT NULL
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
            """)

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

        conn.commit()
        print("mysql_019 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()