如何在Snowflake数据库中解析多层嵌套的未命名JSON数组?
解决Snowflake中嵌套JSON的深层字段解析问题
我来帮你拆解这个问题——你的JSON结构是嵌套的二维数组+对象,只做一次flatten肯定够不到深层的cached字段,咱们一步步来解决:
先明确你的JSON结构
首先看你创建的test2表中json_rec的核心结构:
{ "task_info": { "reps=1": [ [ { "cached": false, "transform max RAM": 51445000 } ], [ { "cached": false, "transform max RAM": 51445000 } ], [ { "cached": true, "transform max RAM": 51445000 } ] ] } }
这里的关键层级是:task_info → 键reps=1 → 外层数组(包含3个子数组) → 子数组(包含1个对象) → 对象中的cached字段。
你的原SQL问题所在
你当前只做了一次flatten,展开的是task_info这个对象的键值对,得到的value是整个外层二维数组([[...], [...], [...]]),而不是单个对象,所以直接用value:cached自然取不到值——数组根本没有cached这个属性。
正确的解析方案
我们需要多次使用LATERAL FLATTEN来逐层展开嵌套结构,分两种场景:
场景1:子数组固定只有1个对象(你的当前场景)
这种情况可以不用额外flatten,直接通过数组索引取对象,效率更高:
SELECT id, json_rec:_id::string(100) AS extracted_id, -- 直接取子数组的第一个元素,再提取cached字段 outer_arr.value[0]:cached::boolean AS cached, outer_arr.value[0]:"transform max RAM"::number AS transform_max_ram, -- 可选:查看中间层级的内容,方便调试 task_flatten.key AS task_key, -- 这里会返回"reps=1" task_flatten.value AS outer_full_array FROM test2 -- 第一步:展开task_info对象的键值对(因为task_info是对象,指定mode='OBJECT') , LATERAL FLATTEN(input => json_rec:task_info, mode => 'OBJECT') AS task_flatten -- 第二步:展开外层数组的每个子数组 , LATERAL FLATTEN(input => task_flatten.value) AS outer_arr
场景2:子数组可能包含多个对象
如果子数组里有多个对象,需要第三次flatten来展开子数组中的对象:
SELECT id, json_rec:_id::string(100) AS extracted_id, -- 从最终展开的对象中提取cached字段 obj.value:cached::boolean AS cached, obj.value:"transform max RAM"::number AS transform_max_ram FROM test2 , LATERAL FLATTEN(input => json_rec:task_info, mode => 'OBJECT') AS task_flatten , LATERAL FLATTEN(input => task_flatten.value) AS outer_arr -- 第三步:展开子数组中的每个对象 , LATERAL FLATTEN(input => outer_arr.value) AS obj
关键知识点
- 当
flatten的输入是对象时,需要指定mode => 'OBJECT'来展开键值对;输入是数组时默认模式即可。 - 多层嵌套的JSON需要逐层
flatten,每次只处理当前层级的数组/对象。 - 对于固定长度的数组,直接用索引(比如
value[0])比额外flatten更高效。
内容的提问来源于stack exchange,提问作者doyouevendata
相关产品推荐
相关产品推荐

