Snowflake - 如何在不聚合的情况下旋转 2 列或多列

问题描述 投票:0回答:1

我是雪花新手,我有一个场景,其中的表格包含以下数据,

Combined1 Combined2 Common_code
Name       John      ABC123
City       NY        ABC123
Sex        M         ABC123
Country    USA       ABC123
Name       John      ABC123
City       BF        ABC123
Sex        M         ABC123
Country    USA       ABC123
Name       Lucy      XYZ456
City       CB        XYZ456
Sex        F         XYZ456
Country    UK        XYZ456

所以我想转置表格,使结果看起来像这样

Name City Sex Country Common_code
John NY   M   USA     ABC123
John BF   M   USA     ABC123
Lucy CB   F   UK      XYZ456

我尝试了多种使用 PIVOT、FLATTEN 的方法,但无法解决这个问题。主要条件是我不想按照上面的示例丢失任何记录。 Snowflake 非常感谢任何回应或解决方案。

pivot snowflake-cloud-data-platform transpose snowflake-stage pivot-without-aggregate
1个回答
0
投票

因此对数据使用 CTE:

with data(Combined1, Combined2, Common_code) as (
    select *
    from values
        ('Name', 'John', 'ABC123'),
        ('City', 'NY', 'ABC123'),
        ('Sex', 'M', 'ABC123'),
        ('Country', 'USA', 'ABC123'),
        ('Name', 'John', 'ABC123'),
        ('City', 'BF', 'ABC123'),
        ('Sex', 'M', 'ABC123'),
        ('Country', 'USA', 'ABC123'),
        ('Name', 'Lucy', 'XYZ456'),
        ('City', 'CB', 'XYZ456'),
        ('Sex', 'F', 'XYZ456'),
        ('Country', 'UK', 'XYZ456')
)

因此,这是您想要避免的最有可能的“最佳”聚合版本,尽管如此,您的 common_code 中有重复的值,因此该数据显得可疑。

select
    max(iff(Combined1='Name',Combined2,null)) as Name
    ,max(iff(Combined1='City',Combined2,null)) as City
    ,max(iff(Combined1='Sex',Combined2,null)) as Sex
    ,max(iff(Combined1='Country',Combined2,null)) as Country
    ,Common_code
from data
group by Common_code
order by Common_code;

但是上述内容依赖于每个感兴趣的事物都不同的“通用代码”。但事实并非如此,因此有两行。

这意味着我们可以用经典的最坏的方式来做,让数据库构建所有组合,然后扔掉大部分工作,方式:

select distinct 
    name.combined2 as name
    ,city.combined2 as City
    ,sex.combined2 as Sex
    ,country.combined2 as Country
    ,name.common_code
from data as name
join data as city
    on name.common_code = city.common_code
        and city.combined1 = 'City'
join data as sex
    on name.common_code = sex.common_code
        and sex.combined1 = 'Sex'
join data as country
    on name.common_code = country.common_code
        and country.combined1 = 'Country'
where name.combined1 = 'Name'
order by name.common_code;

给出:

这可以在子选择(或 CTE)中构建,并使 NATURAL JOIN 也像这样做一些工作:

select distinct
    *
from (
    select combined2 as name, common_code 
    from data 
    where combined1 = 'Name'
) as a
natural join 
(
    select combined2 as city, common_code 
    from data 
    where combined1 = 'City'
) as b
natural join 
(
    select combined2 as sex, common_code 
    from data 
    where combined1 = 'Sex'
) as c  
natural join 
(
    select combined2 as country, common_code 
    from data 
    where combined1 = 'Country'
) as d
;

但现在列顺序不太受我们控制(只是因为我允许连接顺序来定义它)。

© www.soinside.com 2019 - 2024. All rights reserved.