Snowflake中如何将OBJECT_CONSTRUCT生成的JSON键转为小写
问题描述
我有一张结构如下的表:
| ID | DATE | FIRST_NAME | H&P |
|---|---|---|---|
| 12 | 2023-02-01 | JESSICA | 40 |
| 99 | 2023-02-03 | MINA | 98 |
| 12 | 2023-01-14 | JACK | 12 |
执行以下SQL生成带JSON列的表:
SELECT ID, OBJECT_CONSTRUCT(*) as details FROM MY_TABLE;
生成结果:
| ID | DETAILS |
|---|---|
| 12 | {"DATE":"2023-02-01", "FIRST_NAME":"JESSICA", "H&P":"40"} |
| 99 | {"DATE":"2023-02-03", "FIRST_NAME":"MINA", "H&P":"98"} |
| 12 | {"DATE":"2023-01-14", "FIRST_NAME":"JACK", "H&P":"12"} |
我希望生成的JSON键转为小写,值保持不变,得到如下结果:
| ID | DETAILS |
|---|---|
| 12 | {"date":"2023-02-01", "first_name":"JESSICA", "h&p":"40"} |
| 99 | {"date":"2023-02-03", "first_name":"MINA", "h&p":"98"} |
| 12 | {"date":"2023-01-14", "first_name":"JACK", "h&p":"12"} |
注:实际表有近400列,不想手动列出所有列。
解决方案
无需手动枚举列,有两种高效实现方式:
方法1:通过FLATTEN+OBJECT_AGG动态转换
利用内置函数将整行转为JSON后拆分为键值对,转小写键后重新聚合:
SELECT ID, OBJECT_AGG(LOWER(k), v) AS details FROM MY_TABLE, LATERAL FLATTEN(INPUT => OBJECT_CONSTRUCT(*), MODE => 'KEY_VALUE') GROUP BY ID;
逻辑说明:
OBJECT_CONSTRUCT(*)将整行数据转为JSON对象FLATTEN把JSON拆分为逐行的键(k)值(v)对LOWER(k)将键转为小写格式OBJECT_AGG重新聚合为键是小写的JSON对象
方法2:动态生成OBJECT_CONSTRUCT语句
通过查询系统表自动生成包含所有小写键的SQL语句,执行效率更高:
SELECT 'SELECT ID, OBJECT_CONSTRUCT(' || LISTAGG('''' || LOWER(COLUMN_NAME) || ''' , ' || COLUMN_NAME, ', ') || ') AS details FROM MY_TABLE;' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'MY_TABLE' AND COLUMN_NAME != 'ID';
执行这条SQL会输出一条完整的目标查询语句,直接复制执行即可。针对示例表,生成的语句如下:
SELECT ID, OBJECT_CONSTRUCT('date' , DATE, 'first_name' , FIRST_NAME, 'h&p' , "H&P") AS details FROM MY_TABLE;
注:系统会自动处理含特殊字符的列名(如H&P),添加双引号保证语法正确。
内容的提问来源于stack exchange,提问作者Angie
相关产品推荐
相关产品推荐

