为分组依据中的每个分组创建列

时间:2020-07-27 10:29:36

标签: sql snowflake-cloud-data-platform

假设我有一个表T,其中的条目如下:

id   | type   | value   | 
-------------------------
1    | A      | 7
1    | B      | 8
2    | A      | 9
2    | B      | 10
3    | A      | 11
3    | B      | 12
1    | C      | 13
2    | C      | 14

对于每种类型,我想要一个不同的列。由于类型的数量是详尽无遗的,因此我希望列举所有不同的类型,并为每个类型对应一个列。我想将id用作表的主键。

因此,所需的输出类似于:

id   | A's value | B's value | C's value
------------------------------------------
1    | 7         | 8         | 13
2    | 9         | 10        | 14
3    | 11        | 12        | NULL

请注意,这是简化版本。实际表T是使用group by从更大的表派生的。对于每个小组,我想要一个单独的专栏。那有可能吗?

2 个答案:

答案 0 :(得分:3)

我建议查看PIVOT功能:

https://docs.snowflake.com/en/sql-reference/constructs/pivot.html

尽管具有此功能的主要阻止者是数据透视表的值列表 预先确定的。为此,我通常使用LISTAGG函数:

https://docs.snowflake.com/en/sql-reference/functions/listagg.html

我在下面添加了一个查询,以向您展示如何构建该字符串, 并在脚本中一起执行此操作 Python甚至是存储过程都应该非常简单(构建ivot_column,构建aggregate / pivot命令,执行aggregate / pivot命令)。

我希望这可以帮助...丰富

CREATE OR REPLACE TABLE monthly_sales(
    empid   INT, 
    amount  INT, 
    month   TEXT)
AS SELECT * FROM VALUES
    (1, 10000, 'JAN'),
    (1, 400, 'JAN'),
    (2, 4500, 'JAN'),
    (2, 35000, 'JAN'),
    (1, 5000, 'FEB'),
    (1, 3000, 'FEB'),
    (2, 200, 'FEB'),
    (2, 90500, 'FEB'),
    (1, 6000, 'MAR'),
    (1, 5000, 'MAR'),
    (2, 2500, 'MAR'),
    (2, 9500, 'MAR'),
    (1, 8000, 'APR'),
    (1, 10000, 'APR'),
    (2, 800, 'APR'),
    (2, 4500, 'APR');


SELECT * 
FROM monthly_sales
    PIVOT(SUM(amount) 
    FOR month IN ('JAN', 'FEB', 'MAR', 'APR'))
    AS p
ORDER BY empid;

SELECT LISTAGG( DISTINCT  ''''||month||'''',  ', ' ) 
FROM monthly_sales;

答案 1 :(得分:1)

使用条件聚合:

select id,
       max(case when type = 'A' then value end) as a_value,
       max(case when type = 'B' then value end) as b_value,
       max(case when type = 'C' then value end) as c_value
from t
group by id;
相关问题