Oracle 19c中固定列保留原样、动态列转为JSON的查询方案
解决方案
静态列场景(已知需要聚合的列)
如果已经明确要聚合的列(如示例中的col4、col5),可以通过JSON_OBJECT(*)结合EXCLUDE子句排除已知的非聚合列,将聚合结果打包为JSON:
SELECT col1, col2, col3, JSON_OBJECT(*) EXCLUDE (col1, col2, col3) AS sum_json FROM ( -- 原聚合查询作为子查询 SELECT col1, col2, col3, SUM(col4) AS col4, SUM(col5) AS col5 FROM my_table GROUP BY col1, col2, col3 ) t;
EXCLUDE (col1, col2, col3)会从JSON中剔除这三个已知列,只保留聚合后的动态列(col4、col5),最终输出符合col1/col2/col3原样、聚合列打包为JSON的需求。
动态列场景(聚合列名未知)
如果需要聚合的列是动态获取的(比如从元数据中读取),可以通过动态SQL实现:
步骤1:动态生成聚合列列表
从数据字典(如user_tab_columns)中筛选出需要聚合的列(排除col1、col2、col3),拼接成聚合语句:
DECLARE v_sum_cols VARCHAR2(1000); v_full_sql VARCHAR2(2000); BEGIN -- 获取需要聚合的列名,生成sum(列名) as 列名的格式 SELECT LISTAGG('SUM(' || column_name || ') AS ' || column_name, ', ') INTO v_sum_cols FROM user_tab_columns WHERE table_name = 'MY_TABLE' -- 注意表名大写 AND column_name NOT IN ('COL1', 'COL2', 'COL3'); -- 排除已知列 -- 拼接完整的查询SQL v_full_sql := 'SELECT col1, col2, col3, JSON_OBJECT(*) EXCLUDE (col1, col2, col3) AS sum_json FROM (' || 'SELECT col1, col2, col3, ' || v_sum_cols || ' FROM my_table GROUP BY col1, col2, col3) t'; -- 输出生成的SQL(可直接执行,或用EXECUTE IMMEDIATE执行) DBMS_OUTPUT.PUT_LINE(v_full_sql); END; /
步骤2:执行动态生成的SQL
运行上述PL/SQL块后,会输出完整的查询语句,直接执行该语句即可得到目标结果。如果需要自动执行,可替换DBMS_OUTPUT.PUT_LINE(v_full_sql)为EXECUTE IMMEDIATE v_full_sql;(需注意权限和输出处理)。
关键说明
JSON_OBJECT(*)会默认包含所有列,加上EXCLUDE子句可以精准剔除不需要放入JSON的已知列,避免手动枚举动态列的麻烦。- Oracle 19c及以上版本支持
JSON_OBJECT的EXCLUDE/INCLUDE子句,正好适配你的19.17版本。
内容的提问来源于stack exchange,提问作者Bhawana Solanki
相关产品推荐
相关产品推荐

