You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AWS Athena中无需指定所有参数解析JSON到表格?

无需逐个指定参数解析JSON为列的SQL方案

当然可以不用手动逐个指定JSON键来解析列,针对不同的SQL数据库,有对应的动态解析方案,以下是主流引擎的实现方式:

PostgreSQL

PostgreSQL可以通过jsonb_each_text将JSON字段拆分为键值对行,再结合crosstab函数转置为列:

-- 1. 先获取所有唯一的JSON键
WITH all_keys AS (
    SELECT DISTINCT jsonb_object_keys(value::jsonb) AS key
    FROM my_table
),
-- 2. 将JSON拆分为键值对行
key_value_rows AS (
    SELECT 
        event_name,
        key,
        value
    FROM my_table,
    LATERAL jsonb_each_text(value::jsonb)
)
-- 3. 转置为宽表
SELECT *
FROM crosstab(
    'SELECT event_name, key, value FROM key_value_rows ORDER BY 1,2',
    'SELECT key FROM all_keys ORDER BY 1'
) AS ct(event_name text, "link_id" text, "spec" text, "geo" text);

如果键的数量不确定,可以用动态SQL自动生成crosstab的列定义:

DO $$
DECLARE
    cols text;
BEGIN
    SELECT string_agg(DISTINCT quote_ident(key) || ' text', ', ')
    INTO cols
    FROM my_table,
    LATERAL jsonb_object_keys(value::jsonb);

    EXECUTE format('
        SELECT *
        FROM crosstab(
            ''SELECT event_name, key, value FROM (SELECT event_name, key, value FROM my_table, LATERAL jsonb_each_text(value::jsonb)) kv ORDER BY 1,2'',
            ''SELECT DISTINCT key FROM my_table, LATERAL jsonb_object_keys(value::jsonb) ORDER BY 1''
        ) AS ct(event_name text, %s)
    ', cols);
END $$;

BigQuery

BigQuery可以通过UNNEST展开JSON键值对,再用PIVOT转置,结合动态SQL自动生成列:

-- 先获取所有唯一的JSON键
DECLARE keys ARRAY<STRING>;
SET keys = ARRAY(
    SELECT DISTINCT json_extract_scalar(kv, '$.key')
    FROM my_table,
    UNNEST(json_extract_array(json_query(value, '$.keys()'), '$')) kv
);

-- 动态生成PIVOT查询
EXECUTE IMMEDIATE format("""
    SELECT *
    FROM (
        SELECT 
            event_name,
            json_extract_scalar(kv, '$.key') AS key,
            json_extract_scalar(kv, '$.value') AS value
        FROM my_table,
        UNNEST(json_extract_array(json_query(value, '$.entries()'), '$')) kv
    )
    PIVOT (MAX(value) FOR key IN (%s))
""", array_to_string(ARRAY(SELECT CONCAT('"', key, '"') FROM UNNEST(keys)), ', '));

MySQL(8.0+)

MySQL 8.0及以上版本可以用JSON_TABLE展开JSON,再通过动态SQL生成查询:

-- 先获取所有唯一的JSON键
SET @cols = NULL;
SELECT GROUP_CONCAT(DISTINCT CONCAT('MAX(CASE WHEN `key` = ''', `key`, ''' THEN `value` END) AS `', `key`, ''''))
INTO @cols
FROM my_table,
JSON_TABLE(
    value,
    '$.*' COLUMNS (
        `key` VARCHAR(255) PATH '$."key"',
        `value` VARCHAR(255) PATH '$."value"'
    )
) AS jt;

-- 动态生成查询
SET @sql = CONCAT('
    SELECT event_name, ', @cols, '
    FROM my_table,
    JSON_TABLE(
        value,
        ''$.*'' COLUMNS (
            `key` VARCHAR(255) PATH ''$."key"'',
            `value` VARCHAR(255) PATH ''$."value"''
        )
    ) AS jt
    GROUP BY event_name
');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

以上方案都能自动识别JSON中的所有键,无需手动逐个指定,适配你近100个参数的场景。

内容的提问来源于stack exchange,提问作者Smasell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 13:17:36