如何计算雪花数据库变体字段中*** json 键的数量?

Posted

技术标签:

【中文标题】如何计算雪花数据库变体字段中*** json 键的数量?【英文标题】:How can I count the number of top level json keys in a Snowflake database variant field? 【发布时间】:2020-01-01 02:59:49 【问题描述】:

我在这里寻找数字 2...array_size 似乎适用于变体列表,但在此 json 上表现不佳。有没有聪明的方法来做到这一点?我不知道/可能不能相信该结构只会走这么深,并且希望将其用作查询中的另一个字段,在该查询中我从 json 中提取出一堆其他值;所以理想的解决方案也允许这样做。

select dict, array_size(dict)
from (select parse_json('
  "partition": [
    "partition_col"
  ],
  "sample_weight": [
    "sample_weight"
  ]
') as dict)

【问题讨论】:

【参考方案1】:

在这种情况下,您可以创建一个小的 javascript UDF:

create or replace function count_keys(MYVAR variant)
returns float
language javascript
as '
    return (Object.entries(MYVAR)).length
'
;

称呼它:

select count_keys(parse_json(
'
    "partition": [
      "partition_col"
    ],
    "sample_weight": [
      "sample_weight"
    ]
  ')
)
;

【讨论】:

UDF 函数在您的 SQL 代码中看起来比FLATTEN() 更好方式,我相信它的执行速度也明显更快。 有趣的是,在一个包含 1000 个元素的 JSON 的 400K 行测试中,Javascript 用了 17 秒,而 Flatten 在中等 WH 上用了 3 秒。 看来你是对的,我在 X-Small 仓库上得到了 5 分钟对 17 秒。我看到了相反的情况,所以这可能取决于你的情况。但我从没想过会有这么大的差异。【参考方案2】:

使用扁平化:

with dict as (
  select parse_json('
    "partition": [
      "partition_col"
    ],
    "sample_weight": [
      "sample_weight"
    ]
  ') val
)
select val, count(*) 
from   dict,
       lateral flatten(input => val)
group by val
;

【讨论】:

我认为这是一个解决方案;但我不想做类似 count(distinct id) 之类的事情,然后按此记录上的 30 个其他列分组,所以希望有某种更优雅的计数函数可以避免扁平化。 在这种情况下,您可以编写一个 Javascript UDF,返回 JSON 对象中 Object.entries() 的计数...这应该只适用于***对象属性。 @doyouevendata 如果解决了,你能标记解决方案吗?

以上是关于如何计算雪花数据库变体字段中*** json 键的数量?的主要内容,如果未能解决你的问题,请参考以下文章

雪花 - 查询变体中的空值

如何将 Postgres Hstore 数据类型转换为雪花对象或变体

变体列中唯一元素的雪花查询性能

如何从雪花中的变体列创建子集?

雪花变种性能

雪花 JSON 到表格