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

如何在SQL或Python中展开SQL表列中的嵌套JSON数据

如何在SQL或Python中展开SQL表列中的嵌套JSON数据

嘿,我太懂你这种需求了——手里的SQL表混着普通字段和嵌套JSON列,想把那些藏在JSON里的key都拆成单独的列,还得保留原来的id、event_name这些核心数据对吧?我给你分SQL和Python两种常用场景,唠唠实际工作里怎么操作,都是亲测好用的方法~

一、用SQL处理(以BigQuery为例,其他支持JSON的SQL引擎逻辑类似)

首先得把嵌套的JSON数组先“拆平”,再把不同的key转成列。如果你的event_params是字符串类型,得先转成JSON数组;如果已经是数组类型,直接拆就行。

1. 手动指定要展开的key(适合key数量少的情况)

WITH unnested_data AS (
  SELECT
    id,
    event_name,
    param.key AS param_key,
    -- 提取value里的非空值,因为每个value里只有一个字段有数据
    COALESCE(
      param.value.string_value,
      CAST(param.value.int_value AS STRING),
      CAST(param.value.float_value AS STRING),
      CAST(param.value.double_value AS STRING)
    ) AS param_value
  FROM
    your_table,
    -- 如果event_params是字符串,用JSON_EXTRACT_ARRAY转成数组;如果本身是数组,直接写UNNEST(event_params)
    UNNEST(JSON_EXTRACT_ARRAY(event_params)) AS param
)
SELECT
  id,
  event_name,
  -- 把每个key转成对应的列
  MAX(IF(param_key = 'name_attribute1', param_value, NULL)) AS name_attribute1,
  MAX(IF(param_key = 'name_attribute2', param_value, NULL)) AS name_attribute2,
  -- 有其他key就继续加这行格式的语句就行
FROM unnested_data
GROUP BY id, event_name;

2. 动态展开所有key(适合key数量多、不确定的情况)

如果key太多不想手动写,BigQuery可以用动态SQL自动生成透视语句:

DECLARE param_keys ARRAY<STRING>;

-- 先获取所有不同的param_key
SET param_keys = ARRAY(
  SELECT DISTINCT param.key
  FROM your_table,
  UNNEST(JSON_EXTRACT_ARRAY(event_params)) AS param
);

-- 拼接动态透视的SQL语句
EXECUTE IMMEDIATE '''
WITH unnested_data AS (
  SELECT
    id,
    event_name,
    param.key AS param_key,
    COALESCE(
      param.value.string_value,
      CAST(param.value.int_value AS STRING),
      CAST(param.value.float_value AS STRING),
      CAST(param.value.double_value AS STRING)
    ) AS param_value
  FROM your_table,
  UNNEST(JSON_EXTRACT_ARRAY(event_params)) AS param
)
SELECT
  id,
  event_name,
  ''' || ARRAY_TO_STRING(ARRAY(SELECT 'MAX(IF(param_key = "' || key || '", param_value, NULL)) AS `' || key || '`' FROM UNNEST(param_keys) AS key), ', ') || '''
FROM unnested_data
GROUP BY id, event_name;
''';

二、用Python(Pandas)处理

如果更习惯用Python做数据处理,用Pandas就能轻松搞定,步骤大概是“读数据→转JSON→拆数组→透视转列”:

import pandas as pd
import json

# 第一步:从SQL数据库读取数据,这里假设你已经有数据库连接了
df = pd.read_sql("SELECT * FROM your_table", your_database_connection)

# 注意:你的event_params格式不是标准JSON(是key=xxx而不是"key":"xxx"),得先转成标准格式
def fix_non_standard_json(json_str):
    # 把key=xxx替换成标准JSON的键值对格式
    fixed_str = json_str.replace('key=', '"key":').replace('value={', '"value":{')
    fixed_str = fixed_str.replace('string_value=', '"string_value":').replace('int_value=', '"int_value":')
    fixed_str = fixed_str.replace('float_value=', '"float_value":').replace('double_value=', '"double_value":')
    # 处理null和括号,确保能被json.loads解析
    fixed_str = fixed_str.replace('null', 'null').replace('}', '}').replace('{', '{')
    return fixed_str

# 把event_params列转成Python的列表字典
df['event_params'] = df['event_params'].apply(fix_non_standard_json).apply(json.loads)

# 第二步:把嵌套的数组拆成单独的行
df_exploded = df.explode('event_params').reset_index(drop=True)

# 第三步:提取每个param的key和对应的有效value
df_exploded['param_key'] = df_exploded['event_params'].apply(lambda x: x['key'])
df_exploded['param_value'] = df_exploded['event_params'].apply(lambda x: 
    # 取第一个非空的value值
    x['value']['string_value'] or x['value']['int_value'] or x['value']['float_value'] or x['value']['double_value']
)

# 第四步:透视,把key转成列,合并回原有的id和event_name
df_pivoted = df_exploded.pivot(index=['id', 'event_name'], columns='param_key', values='param_value').reset_index()

# 现在df_pivoted就是你要的结构啦,每个key对应一列
print(df_pivoted.head())

如果你的event_params已经是标准JSON格式,那可以跳过fix_non_standard_json这个函数,直接用json.loads解析就行。

备注:内容来源于stack exchange,提问作者João Bugelli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 07:35:36