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

Snowflake中JSON遍历如何忽略元素名称大小写?

Snowflake处理JSON大小写不统一的字段提取方案

问题场景

Snowflake中遍历JSON时元素名称严格区分大小写,当JSON字段存在大小写变体(如示例中的PromoCode和promoCode),原查询仅提取PromoCode会遗漏promoCode对应的数据(如order_id=333的ccc值)。

订单表示例:

order_idpromo_json_array
111[{PromoCode:"bbb", Discount: -1 }, {PromoCode:"aaa", Type:FreeShip}]
222[{PromoCode:"ccc", Discount: -2}]
333[{promoCode:"ccc", Discount: -2}, {PromoCode:"aaa"}, {PromoCode:"eee"} ]
444

原查询(存在遗漏问题):

with orders as (
  select 111 as order_id, '[{PromoCode:"bbb", Discount: -1 }, {PromoCode:"aaa", Type:"FreeShip"}]' as promo_json_array
  union all
  select 222, '[{PromoCode:"ccc", Discount: -2}]'
  union all
  select 333, '[{promoCode:"ccc", Discount: -2}, {PromoCode:"aaa"}, {PromoCode:"eee"} ]'
  union all
  select 444, null
)
select order_id, f.value:PromoCode::string,
from orders
, lateral flatten(input => parse_json(orders.promo_json_array)::variant, OUTER => TRUE) as f
group by all;

最佳处理方案

方案1:COALESCE匹配所有已知大小写变体

如果字段大小写变体数量少且明确,直接用COALESCE依次尝试所有可能的键名,确保不遗漏数据。

修改后查询:

with orders as (
  select 111 as order_id, '[{PromoCode:"bbb", Discount: -1 }, {PromoCode:"aaa", Type:"FreeShip"}]' as promo_json_array
  union all
  select 222, '[{PromoCode:"ccc", Discount: -2}]'
  union all
  select 333, '[{promoCode:"ccc", Discount: -2}, {PromoCode:"aaa"}, {PromoCode:"eee"} ]'
  union all
  select 444, null
)
select 
  order_id, 
  COALESCE(f.value:PromoCode::string, f.value:promoCode::string) as promo_code
from orders
, lateral flatten(input => parse_json(orders.promo_json_array)::variant, OUTER => TRUE) as f
group by all;

优点:实现简单,性能开销小;缺点:无法覆盖未知的大小写变体(如PROMOCODE)。

方案2:统一转换JSON键为小写(或大写)后提取

如果字段变体多或不确定,先将JSON对象的所有键转换为统一大小写(如全小写),再提取目标字段,彻底解决大小写问题。

使用OBJECT_CONSTRUCT_LOWER函数转换键为小写,再提取promocode:

with orders as (
  select 111 as order_id, '[{PromoCode:"bbb", Discount: -1 }, {PromoCode:"aaa", Type:"FreeShip"}]' as promo_json_array
  union all
  select 222, '[{PromoCode:"ccc", Discount: -2}]'
  union all
  select 333, '[{promoCode:"ccc", Discount: -2}, {PromoCode:"aaa"}, {PromoCode:"eee"} ]'
  union all
  select 444, null
)
select 
  order_id, 
  -- 将每个JSON对象的键转成小写,再提取统一的promocode字段
  OBJECT_CONSTRUCT_LOWER(f.value):promocode::string as promo_code
from orders
, lateral flatten(input => parse_json(orders.promo_json_array)::variant, OUTER => TRUE) as f
group by all;

优点:一次性覆盖所有大小写变体,扩展性强;缺点:对复杂嵌套JSON的转换会有轻微性能开销,可忽略不计。

方案3:动态遍历键名匹配(适合极端变体场景)

如果键名大小写完全无规律,可通过OBJECT_KEYS遍历所有键,匹配忽略大小写的目标字段名:

with orders as (
  select 111 as order_id, '[{PromoCode:"bbb", Discount: -1 }, {PromoCode:"aaa", Type:"FreeShip"}]' as promo_json_array
  union all
  select 222, '[{PromoCode:"ccc", Discount: -2}]'
  union all
  select 333, '[{promoCode:"ccc", Discount: -2}, {PromoCode:"aaa"}, {PromoCode:"eee"} ]'
  union all
  select 444, null
)
select 
  order_id,
  -- 遍历所有键,找到忽略大小写匹配"promocode"的键对应值
  MAX(CASE WHEN LOWER(k.key) = 'promocode' THEN f.value[k.key]::string END) as promo_code
from orders
, lateral flatten(input => parse_json(orders.promo_json_array)::variant, OUTER => TRUE) as f
, lateral flatten(input => OBJECT_KEYS(f.value)) as k
group by order_id, f.value;

优点:完全兼容任意大小写变体;缺点:需要额外展开键名,性能开销略高,仅适合极端场景。


内容的提问来源于stack exchange,提问作者Saqib Ali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:15:17