# URL Safety Detection Multi-Dimensional Access Statistics Report (MySQL)

## Prompt
I need you to generate a MySQL script that computes multi-dimensional access statistics from the URL safety detection detail table, producing a URL access statistics report.

**Business Background and Objective**: The URL safety detection system collects URL access records for each `taid` daily. It needs to compute UV and its 1d/7d/30d/1m periodic metrics across multiple dimensions (taid, taid+url, taid+domain/site, taid+cgi), and output a single-row summary result to the report table.

**Input Tables (full name + brief description)**:
- `internal_platform_db.t_dws_urlsafe_rela_mobile_browser_taid_url_di_mysql_018` (URL safety detection detail table)
- Historical partition data: Historical records in the output table itself where `ds = 20260531, channel = 'mobile_browser'` (left join source, used to obtain 1m metrics)

(Please connect to the database and query to confirm the table structures and field semantics.)

**Filter Condition**:
- Input table: `ds > 20260509 AND ds <= 20260608`

**Processing Rules**:
### Subquery a (taid-level UV statistics)
- Group by `taid`, compute:
  - `uv_1d = COUNT(IF(ds_max = 20260608, 1, NULL))`
  - `uv_avg_7d = (COUNT(state_6d=1) + ... + COUNT(state_daily=1)) / 7`, where `state_*d = MAX(IF(ds = corresponding_date, 1, 0))`
  - `uv_7d = COUNT(IF(ds_max > 20260601, 1, NULL))`
  - `uv_30d = COUNT(1)`

### Subquery c (taid+url-level statistics)
- Group by `taid`, `url` and aggregate, computing `userid_url_1d`/`avg_7d`/`7d`/`30d` using the same logic as above

### Subquery d (taid+domain/site-level statistics)
- First group by `taid`, `site` and aggregate `domain`, `ds_max`, `state_*d`
  - Domain value rule: Under the same taid+site, if multiple domains exist, take `MAX(domain)` (lexicographically largest value) as the domain attribution for that site
- Then group by `taid`, `domain` and aggregate, computing:
  - `userid_domain_1d`/`avg_7d`/`7d`/`30d`
  - `userid_site_1d = SUM(site_cnt_daily)`
  - `userid_site_avg_7d = (SUM(site_cnt_6d) + ... + SUM(site_cnt_daily)) / 7`
  - `userid_site_7d = SUM(site_cnt_7d)`
  - `userid_site_30d = SUM(site_cnt)`

### Subquery e (taid+cgi-level statistics)
- Group by `taid`, `cgi` and aggregate, computing `userid_cgi_1d`/`avg_7d`/`7d`/`30d` using the same logic as above

### Join Logic
- `a LEFT JOIN b` (historical partition, joined on `data_par`): `IFNULL(b.uv_1m, 0)` and 4 other fields
- `a JOIN c, d, e` (all inner joins, joined on `data_par`)

### Final Output Fields (in order)
- `access_type = '网址检测API'`
- `access_channel = '手机IM平台Q浏览器'`
- `uv_1d`, `uv_avg_7d` (`ROUND(x, 0)`), `uv_7d`, `uv_30d`, `uv_1m`
- `userid_url_1d`, `userid_url_avg_7d` (ROUND), `userid_url_7d`, `userid_url_30d`, `userid_url_1m`
- `userid_domain_1d`, `userid_domain_avg_7d` (ROUND), `userid_domain_7d`, `userid_domain_30d`, `userid_domain_1m`
- `userid_site_1d`, `userid_site_avg_7d` (ROUND), `userid_site_7d`, `userid_site_30d`, `userid_site_1m`
- `userid_cgi_1d`, `userid_cgi_avg_7d` (ROUND), `userid_cgi_7d`, `userid_cgi_30d`, `userid_cgi_1m`

**Output Requirements**:
- Target table: `internal_platform_db.t_app_urlsafe_report_url_access_stat_di_cand_mysql_018`
- Single-row result, 27 fields
- All avg fields retain 0 decimal places (using ROUND)
- 1m fields use IFNULL to handle NULL as 0
- If the target table does not exist, first create it using standard MySQL InnoDB format, then write the data
- Use standard MySQL syntax; do not use Hive/Spark SQL dialects

**Environment and Execution Notes**:
- Your final output must be written to the file `/tmp_workspace/result.py`, not `result.sql`
- The local MySQL is running at localhost:3306, username `root`, password `root123`
- Use Python `pymysql` in `result.py` to execute the SQL (do not use the `mysql` command-line tool)
- The script must include complete table creation (if the target table does not exist) and data writing logic
- After writing `result.py`, you must execute `python3 /tmp_workspace/result.py` yourself to verify that it runs successfully and produces correct data

## Reference Solution
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
mysql_018 ground truth: 网址安全检测多维度访问统计报表

Task:
  From URL safety detection detail table, compute multi-dimensional
  access statistics (UV metrics at taid/url/domain/site/cgi levels),
  join with historical partition data, and write single-row result
  to output table.
"""
import pymysql
import sys

DB_NAME = "internal_platform_db"
INPUT_TABLE = "t_dws_urlsafe_rela_mobile_browser_taid_url_di_mysql_018"
OUTPUT_TABLE = "t_app_urlsafe_report_url_access_stat_di_mysql_018"
CAND_TABLE = "t_app_urlsafe_report_url_access_stat_di_cand_mysql_018"

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

# MySQL-adapted GT SQL:
# - INSERT OVERWRITE -> INSERT INTO ... SELECT
# - NVL -> IFNULL
# - to_char(date_sub(...)) -> hardcoded 20260531
# - PARTITION columns become regular columns
gt_sql = f"""
INSERT INTO {DB_NAME}.{CAND_TABLE}
    (access_type, access_channel,
     uv_1d, uv_avg_7d, uv_7d, uv_30d, uv_1m,
     userid_url_1d, userid_url_avg_7d, userid_url_7d, userid_url_30d, userid_url_1m,
     userid_domain_1d, userid_domain_avg_7d, userid_domain_7d, userid_domain_30d, userid_domain_1m,
     userid_site_1d, userid_site_avg_7d, userid_site_7d, userid_site_30d, userid_site_1m,
     userid_cgi_1d, userid_cgi_avg_7d, userid_cgi_7d, userid_cgi_30d, userid_cgi_1m,
     ds, channel)
SELECT
    '网址检测API' AS access_type,
    '手机IM平台Q浏览器' AS access_channel,
    a.uv_1d,
    ROUND(a.uv_avg_7d, 0) AS uv_avg_7d,
    a.uv_7d,
    a.uv_30d,
    IFNULL(b.uv_1m, 0) AS uv_1m,
    c.userid_url_1d,
    ROUND(c.userid_url_avg_7d, 0) AS userid_url_avg_7d,
    c.userid_url_7d,
    c.userid_url_30d,
    IFNULL(b.userid_url_1m, 0) AS userid_url_1m,
    d.userid_domain_1d,
    ROUND(d.userid_domain_avg_7d, 0) AS userid_domain_avg_7d,
    d.userid_domain_7d,
    d.userid_domain_30d,
    IFNULL(b.userid_domain_1m, 0) AS userid_domain_1m,
    d.userid_site_1d,
    ROUND(d.userid_site_avg_7d, 0) AS userid_site_avg_7d,
    d.userid_site_7d,
    d.userid_site_30d,
    IFNULL(b.userid_site_1m, 0) AS userid_site_1m,
    e.userid_cgi_1d,
    ROUND(e.userid_cgi_avg_7d, 0) AS userid_cgi_avg_7d,
    e.userid_cgi_7d,
    e.userid_cgi_30d,
    IFNULL(b.userid_cgi_1m, 0) AS userid_cgi_1m,
    20260608 AS ds,
    'mobile_browser' AS channel
FROM
(
    SELECT 20260608 AS data_par,
        COUNT(IF(ds_max = 20260608, 1, NULL)) AS uv_1d,
        (COUNT(IF(state_6d=1,1,NULL))+COUNT(IF(state_5d=1,1,NULL))+COUNT(IF(state_4d=1,1,NULL))+COUNT(IF(state_3d=1,1,NULL))+COUNT(IF(state_2d=1,1,NULL))+COUNT(IF(state_1d=1,1,NULL))+COUNT(IF(state_daily=1,1,NULL)))/7 AS uv_avg_7d,
        COUNT(IF(ds_max > 20260601, 1, NULL)) AS uv_7d,
        COUNT(1) AS uv_30d
    FROM
    (
        SELECT taid,
            MAX(ds) AS ds_max,
            MAX(IF(ds = 20260602,1,0)) AS state_6d,
            MAX(IF(ds = 20260603,1,0)) AS state_5d,
            MAX(IF(ds = 20260604,1,0)) AS state_4d,
            MAX(IF(ds = 20260605,1,0)) AS state_3d,
            MAX(IF(ds = 20260606,1,0)) AS state_2d,
            MAX(IF(ds = 20260607,1,0)) AS state_1d,
            MAX(IF(ds = 20260608,1,0)) AS state_daily
        FROM {DB_NAME}.{INPUT_TABLE}
        WHERE ds > 20260509 AND ds <= 20260608
        GROUP BY taid
    ) t
) a
LEFT JOIN
(
    SELECT 20260608 AS data_par,
        uv_30d AS uv_1m,
        userid_url_30d AS userid_url_1m,
        userid_domain_30d AS userid_domain_1m,
        userid_site_30d AS userid_site_1m,
        userid_cgi_30d AS userid_cgi_1m
    FROM {DB_NAME}.{OUTPUT_TABLE}
    WHERE ds = 20260531
    AND channel = 'mobile_browser'
) b ON a.data_par = b.data_par
JOIN
(
    SELECT 20260608 AS data_par,
        COUNT(IF(ds_max = 20260608, 1, NULL)) AS userid_url_1d,
        (COUNT(IF(state_6d=1,1,NULL))+COUNT(IF(state_5d=1,1,NULL))+COUNT(IF(state_4d=1,1,NULL))+COUNT(IF(state_3d=1,1,NULL))+COUNT(IF(state_2d=1,1,NULL))+COUNT(IF(state_1d=1,1,NULL))+COUNT(IF(state_daily=1,1,NULL)))/7 AS userid_url_avg_7d,
        COUNT(IF(ds_max > 20260601, 1, NULL)) AS userid_url_7d,
        COUNT(1) AS userid_url_30d
    FROM
    (
        SELECT taid,
            url,
            MAX(ds) AS ds_max,
            MAX(IF(ds = 20260602,1,0)) AS state_6d,
            MAX(IF(ds = 20260603,1,0)) AS state_5d,
            MAX(IF(ds = 20260604,1,0)) AS state_4d,
            MAX(IF(ds = 20260605,1,0)) AS state_3d,
            MAX(IF(ds = 20260606,1,0)) AS state_2d,
            MAX(IF(ds = 20260607,1,0)) AS state_1d,
            MAX(IF(ds = 20260608,1,0)) AS state_daily
        FROM {DB_NAME}.{INPUT_TABLE}
        WHERE ds > 20260509 AND ds <= 20260608
        GROUP BY taid, url
    ) t
) c ON a.data_par = c.data_par
JOIN
(
    SELECT 20260608 AS data_par,
        COUNT(IF(ds_max = 20260608, 1, NULL)) AS userid_domain_1d,
        (COUNT(IF(state_6d=1,1,NULL))+COUNT(IF(state_5d=1,1,NULL))+COUNT(IF(state_4d=1,1,NULL))+COUNT(IF(state_3d=1,1,NULL))+COUNT(IF(state_2d=1,1,NULL))+COUNT(IF(state_1d=1,1,NULL))+COUNT(IF(state_daily=1,1,NULL)))/7 AS userid_domain_avg_7d,
        COUNT(IF(ds_max > 20260601, 1, NULL)) AS userid_domain_7d,
        COUNT(1) AS userid_domain_30d,
        SUM(site_cnt_daily) AS userid_site_1d,
        (SUM(site_cnt_6d)+SUM(site_cnt_5d)+SUM(site_cnt_4d)+SUM(site_cnt_3d)+SUM(site_cnt_2d)+SUM(site_cnt_1d)+SUM(site_cnt_daily))/7 AS userid_site_avg_7d,
        SUM(site_cnt_7d) AS userid_site_7d,
        SUM(site_cnt) AS userid_site_30d
    FROM
    (
        SELECT taid,
            domain,
            MAX(ds_max) AS ds_max,
            MAX(IF(state_6d=1,1,0)) AS state_6d,
            MAX(IF(state_5d=1,1,0)) AS state_5d,
            MAX(IF(state_4d=1,1,0)) AS state_4d,
            MAX(IF(state_3d=1,1,0)) AS state_3d,
            MAX(IF(state_2d=1,1,0)) AS state_2d,
            MAX(IF(state_1d=1,1,0)) AS state_1d,
            MAX(IF(state_daily=1,1,0)) AS state_daily,
            COUNT(1) AS site_cnt,
            COUNT(IF(state_6d=1,1,NULL)) AS site_cnt_6d,
            COUNT(IF(state_5d=1,1,NULL)) AS site_cnt_5d,
            COUNT(IF(state_4d=1,1,NULL)) AS site_cnt_4d,
            COUNT(IF(state_3d=1,1,NULL)) AS site_cnt_3d,
            COUNT(IF(state_2d=1,1,NULL)) AS site_cnt_2d,
            COUNT(IF(state_1d=1,1,NULL)) AS site_cnt_1d,
            COUNT(IF(ds_max = 20260608,1,NULL)) AS site_cnt_daily,
            COUNT(IF(ds_max > 20260601,1,NULL)) AS site_cnt_7d
        FROM
        (
            SELECT taid,
                site,
                MAX(domain) AS domain,
                MAX(ds) AS ds_max,
                MAX(IF(ds = 20260602,1,0)) AS state_6d,
                MAX(IF(ds = 20260603,1,0)) AS state_5d,
                MAX(IF(ds = 20260604,1,0)) AS state_4d,
                MAX(IF(ds = 20260605,1,0)) AS state_3d,
                MAX(IF(ds = 20260606,1,0)) AS state_2d,
                MAX(IF(ds = 20260607,1,0)) AS state_1d,
                MAX(IF(ds = 20260608,1,0)) AS state_daily
            FROM {DB_NAME}.{INPUT_TABLE}
            WHERE ds > 20260509 AND ds <= 20260608
            GROUP BY taid, site
        ) t1
        GROUP BY taid, domain
    ) t
) d ON a.data_par = d.data_par
JOIN
(
    SELECT 20260608 AS data_par,
        COUNT(IF(ds_max = 20260608, 1, NULL)) AS userid_cgi_1d,
        (COUNT(IF(state_6d=1,1,NULL))+COUNT(IF(state_5d=1,1,NULL))+COUNT(IF(state_4d=1,1,NULL))+COUNT(IF(state_3d=1,1,NULL))+COUNT(IF(state_2d=1,1,NULL))+COUNT(IF(state_1d=1,1,NULL))+COUNT(IF(state_daily=1,1,NULL)))/7 AS userid_cgi_avg_7d,
        COUNT(IF(ds_max > 20260601, 1, NULL)) AS userid_cgi_7d,
        COUNT(1) AS userid_cgi_30d
    FROM
    (
        SELECT taid,
            cgi,
            MAX(ds) AS ds_max,
            MAX(IF(ds = 20260602,1,0)) AS state_6d,
            MAX(IF(ds = 20260603,1,0)) AS state_5d,
            MAX(IF(ds = 20260604,1,0)) AS state_4d,
            MAX(IF(ds = 20260605,1,0)) AS state_3d,
            MAX(IF(ds = 20260606,1,0)) AS state_2d,
            MAX(IF(ds = 20260607,1,0)) AS state_1d,
            MAX(IF(ds = 20260608,1,0)) AS state_daily
        FROM {DB_NAME}.{INPUT_TABLE}
        WHERE ds > 20260509 AND ds <= 20260608
        GROUP BY taid, cgi
    ) t1
) e ON a.data_par = e.data_par
"""


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}.{CAND_TABLE} (
                    access_type        VARCHAR(256)  DEFAULT NULL COMMENT '访问类型',
                    access_channel     VARCHAR(256)  DEFAULT NULL COMMENT '访问渠道',
                    uv_1d              BIGINT        DEFAULT NULL COMMENT '1日UV',
                    uv_avg_7d          BIGINT        DEFAULT NULL COMMENT '7日平均UV',
                    uv_7d              BIGINT        DEFAULT NULL COMMENT '7日UV',
                    uv_30d             BIGINT        DEFAULT NULL COMMENT '30日UV',
                    uv_1m              BIGINT        DEFAULT NULL COMMENT '1月UV',
                    userid_url_1d      BIGINT        DEFAULT NULL COMMENT 'URL维度1日用户数',
                    userid_url_avg_7d  BIGINT        DEFAULT NULL COMMENT 'URL维度7日平均用户数',
                    userid_url_7d      BIGINT        DEFAULT NULL COMMENT 'URL维度7日用户数',
                    userid_url_30d     BIGINT        DEFAULT NULL COMMENT 'URL维度30日用户数',
                    userid_url_1m      BIGINT        DEFAULT NULL COMMENT 'URL维度1月用户数',
                    userid_domain_1d   BIGINT        DEFAULT NULL COMMENT '域名维度1日用户数',
                    userid_domain_avg_7d BIGINT        DEFAULT NULL COMMENT '域名维度7日平均用户数',
                    userid_domain_7d   BIGINT        DEFAULT NULL COMMENT '域名维度7日用户数',
                    userid_domain_30d  BIGINT        DEFAULT NULL COMMENT '域名维度30日用户数',
                    userid_domain_1m   BIGINT        DEFAULT NULL COMMENT '域名维度1月用户数',
                    userid_site_1d     BIGINT        DEFAULT NULL COMMENT '站点维度1日用户数',
                    userid_site_avg_7d BIGINT        DEFAULT NULL COMMENT '站点维度7日平均用户数',
                    userid_site_7d     BIGINT        DEFAULT NULL COMMENT '站点维度7日用户数',
                    userid_site_30d    BIGINT        DEFAULT NULL COMMENT '站点维度30日用户数',
                    userid_site_1m     BIGINT        DEFAULT NULL COMMENT '站点维度1月用户数',
                    userid_cgi_1d      BIGINT        DEFAULT NULL COMMENT 'CGI维度1日用户数',
                    userid_cgi_avg_7d  BIGINT        DEFAULT NULL COMMENT 'CGI维度7日平均用户数',
                    userid_cgi_7d      BIGINT        DEFAULT NULL COMMENT 'CGI维度7日用户数',
                    userid_cgi_30d     BIGINT        DEFAULT NULL COMMENT 'CGI维度30日用户数',
                    userid_cgi_1m      BIGINT        DEFAULT NULL COMMENT 'CGI维度1月用户数',
                    ds                 BIGINT        DEFAULT NULL COMMENT '日期分区',
                    channel            VARCHAR(256)  DEFAULT NULL COMMENT '渠道分区'
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
            """)

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

        conn.commit()
        print("mysql_018 ground_truth done: 1 row 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()