DB2 V11多对多连接数据膨胀,寻求替代JSON_ARRAYAGG的Python方案
解决DB2 V11多对多表连接冗余及JSON聚合问题
针对DB2 V11不支持JSON_ARRAYAGG的情况,你可以通过Python实现聚合需求,也可以用DB2原生函数替代,以下是具体方案:
一、Python实现方案
将数据拉取到Python端进行分组聚合,避免DB2端产生大量冗余连接数据,适合9万行级别的数据量:
1. 安装依赖
pip install pandas ibm_db ibm_db_sa sqlalchemy
2. 数据聚合与连接示例
import pandas as pd import json from sqlalchemy import create_engine # 连接DB2数据库(替换为你的实际连接信息) conn_str = "ibm_db_sa://username:password@host:port/database" engine = create_engine(conn_str) # 读取数据集1并聚合为JSON格式 df_inc = pd.read_sql("SELECT FP_ID, WS_ID, SC_ID, INC_NUM, INC_DESC FROM 数据集1", engine) df_inc_agg = df_inc.groupby(['FP_ID', 'WS_ID', 'SC_ID']).apply( lambda x: json.dumps(x[['INC_NUM', 'INC_DESC']].to_dict('records')) ).reset_index(name='INC_DTL') # 读取数据集2并做同样聚合处理 df_rsk = pd.read_sql("SELECT FP_ID, WS_ID, SC_ID, RSK_NUM, RSK_DESC FROM 数据集2", engine) df_rsk_agg = df_rsk.groupby(['FP_ID', 'WS_ID', 'SC_ID']).apply( lambda x: json.dumps(x[['RSK_NUM', 'RSK_DESC']].to_dict('records')) ).reset_index(name='RSK_DTL') # 执行连接操作(按需选择inner/outer join) final_df = pd.merge(df_inc_agg, df_rsk_agg, on=['FP_ID', 'WS_ID', 'SC_ID'], how='outer') # 可选:将结果写回DB2 final_df.to_sql('聚合后连接结果表', engine, if_exists='replace', index=False)
二、DB2 V11原生替代方案
如果不想依赖Python,可通过DB2内置函数实现JSON聚合:
方式1:用LISTAGG手动拼接JSON字符串
通过字符串拼接生成符合格式的JSON数组,需处理字段中的特殊字符:
-- 处理数据集1 SELECT FP_ID, WS_ID, SC_ID, '[' || LISTAGG('{"INC_NUM":' || INC_NUM || ',"INC_DESC":"' || REPLACE(INC_DESC, '"', '\"') || '"}', ',') WITHIN GROUP (ORDER BY INC_NUM) || ']' AS INC_DTL FROM 数据集1 GROUP BY FP_ID, WS_ID, SC_ID; -- 处理数据集2 SELECT FP_ID, WS_ID, SC_ID, '[' || LISTAGG('{"RSK_NUM":' || RSK_NUM || ',"RSK_DESC":"' || REPLACE(RSK_DESC, '"', '\"') || '"}', ',') WITHIN GROUP (ORDER BY RSK_NUM) || ']' AS RSK_DTL FROM 数据集2 GROUP BY FP_ID, WS_ID, SC_ID;
方式2:用XMLAGG转JSON(更可靠)
利用DB2的XML函数生成XML后转换为标准JSON,避免手动拼接的格式风险:
-- 处理数据集1 SELECT FP_ID, WS_ID, SC_ID, XMLSERIALIZE( XMLJSON( XMLELEMENT( NAME "array", XMLAGG( XMLELEMENT( NAME "object", XMLELEMENT(NAME "INC_NUM", INC_NUM), XMLELEMENT(NAME "INC_DESC", INC_DESC) ) ) ) ) AS CLOB(1M) ) AS INC_DTL FROM 数据集1 GROUP BY FP_ID, WS_ID, SC_ID; -- 处理数据集2的SQL逻辑类似,替换字段名即可
三、聚合后连接处理
无论用哪种方式生成聚合表,后续通过连接字段关联即可,此时数据量已大幅压缩:
SELECT a.FP_ID, a.WS_ID, a.SC_ID, a.INC_DTL, b.RSK_DTL FROM 聚合后数据集1 a FULL OUTER JOIN 聚合后数据集2 b ON a.FP_ID = b.FP_ID AND a.WS_ID = b.WS_ID AND a.SC_ID = b.SC_ID;
内容的提问来源于stack exchange,提问作者Koushik Chandra
相关产品推荐
相关产品推荐

