在雪花的特定位置用特定值填充数组

Populate an array with certain values at certain positions in snowflake

假设我有这个 table:

Key Index Value
1 3 10
1 5 18
1 14 4
2 2 11
2 13 24
2 29 40

我想在 Snowflake 中构建一个数组,其中数组的维度始终为 50,默认值为零,并且我想根据索引和值列在特定位置用特定值填充数组。期望的输出是

Key Array
1 [0,0,0,10,0,18,0,0,0,0,0,0,0,0,4,0,...,0]
2 [0,0,11,0,...,0,24,0,...,0,40,0,...,0]

也许是这样的。

with my_data as (
    -- data table as cte
    select
        1 as Key,
        3 as Index,
        10 as Value
    union all
    select
        1,
        5,
        18
    union all
    select
        1,
        14,
        4
    union all
    select
        2,
        2,
        11
    union all
    select
        2,
        13,
        24
    union all
    select
        2,
        29,
        40
),
index_cte as (
    -- generate 1-50 index values
    select
        row_number() over (
            order by
                seq4()
        ) as fixed_index
    from
        table(generator(rowcount => 50))
),
keys_fixed_index as(
    -- cross join distinct keys with fixed_index values
    select
        distinct key,
        fixed_index
    from
        my_data
        cross join index_cte
)
select
    distinct
    t1.key,
    ARRAY_AGG(ifnull(value, 0)) WITHIN GROUP (
        order by
            t1.fixed_index asc
    ) OVER (PARTITION BY t1.key) as array
from
    keys_fixed_index t1
    left join my_data t2 on t1.key = t2.key
    and t1.fixed_index = t2.index
order by
    key
KEY ARRAY
1 [ 0, 0, 10, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
2 [ 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]

更新为使用基于集合的方法

这可以使用基于集合的方法以更简单的方式完成,而不是使用字符串操作和聚合。我不知道为什么我没有早点想到它。

with cte as

(select key,
        row_number() over (partition by key order by 1)-1 as index, 
        0 as value
 from table(generator(rowcount=>50)) cross join (select distinct key from t)

 union
 select key,index,value 
 from t

 minus
 select key,index,0
 from t)

select key,array_agg(value) within group (order by index) as value_array
from cte
group by key