sql - 为 group by 中的每个组创建列
问题描述
假设我有一个表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
. 对于每个组,我想要一个单独的专栏。这甚至可能吗?
解决方案
我建议查看 PIVOT 功能:
https://docs.snowflake.com/en/sql-reference/constructs/pivot.html
不过,这个函数的主要障碍是需要预先确定 pivot_column 的值列表。为此,我通常使用 LISTAGG 函数:
https://docs.snowflake.com/en/sql-reference/functions/listagg.html
我在下面包含了一个查询,向您展示如何构建该字符串,并且在 Python 之类的脚本甚至存储过程中一起执行此操作应该相当简单(构建 pivot_column,构建聚合/数据透视命令,执行聚合/枢轴命令)。
我希望这会有所帮助...丰富
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;
推荐阅读
- sql - 如何将包含数据库的 SQL 创建和插入语句的文本文件导入 SAS Studio?
- perl - 欧拉项目 1 号 perl
- python - @patch 模拟到 mysqldb 的连接不起作用
- python - 如何在列表中创建给定字母组合的所有可能子集?
- algorithm - 组合两个列表并均匀分布内容的算法
- postgresql - 如果使用 WAL-G,删除旧的完整备份时旧的 wal 文件会发生什么?
- kotlin - Kotlin 意外的赋值值
- android - Android 房间查询:文本完全匹配搜索字符串或以搜索字符串开头
- python - 如何在python中获取日期范围内某些特定工作日的列表
- javascript - 没有指定默认引擎,也没有提供扩展名