我有一个包含客户数据的表,以及每行值数、列前缀和填充值的变量。
我正在尝试编写一个动态 SQL 查询,将基于 ID 列的客户数据转置到每行指定列数的新表中,并以列前缀和序号命名。如果任何列没有数据,则应使用填充值。
示例:
输入表:
客户_ID | 客户值 |
---|---|
1 | CI10 |
1 | CI11 |
1 | CI12 |
1 | CI13 |
1 | CI14 |
2 | CI20 |
变量:
values_per_row = 2
col_prefix = 'CV_'
filler_value = 'XX'
预期输出:
当values_per_row为2时:
身份证 | CV_1 | CV_2 |
---|---|---|
1 | CI10 | CI11 |
1 | CI12 | CI13 |
1 | CI14 | XX |
2 | CI20 | XX |
当values_per_row为3时:
身份证 | CV_1 | CV_2 | CV_3 |
---|---|---|---|
1 | CI10 | CI11 | CI12 |
1 | CI13 | CI14 | XX |
2 | CI20 | XX | XX |
最终输出应具有基于 col_prefix 和values_per_row 变量的列名称。该解决方案应该灵活且可重用,以便可以用于基于变量转置数据。
一段时间以来,我一直在努力在雪花中有效地生成它。非常感谢任何帮助/见解。
您必须修改 SQL 以适应所需输出列的数量,但这会提供 3 列的所需输出
with t0(cust_id, cust_value) as (
select * from values
(1, 'CI10'),
(1, 'CI11'),
(1, 'CI12'),
(1, 'CI13'),
(1, 'CI14'),
(2, 'CI20')
), t1 as (
select
*,
row_number() over (partition by cust_id order by cust_value)-1 as rn
from t0
)
select
cust_id,
max(case when rn %3 = 0 then cust_value end) as cv_1,
ifnull(max(case when rn %3 = 1 then cust_value end),'XX') as cv_2,
ifnull(max(case when rn %3 = 2 then cust_value end),'XX') as cv_3
from t1
group by cust_id, floor(rn/3)
order by cust_id, floor(rn/3)
;
CUST_ID | CV_1 | CV_2 | CV_3 |
---|---|---|---|
1 | CI1O | CI11 | CI12 |
1 | CI13 | CI14 | XX |
2 | CI20 | XX | XX |