POSTGRESQL中如何将多行不同值数据转换为单行多列格式
PostgreSQL多行转多列实现方案
方案1:条件聚合(无需额外扩展,推荐新手使用)
不需要安装任何扩展,通过CASE WHEN搭配聚合函数即可实现,逻辑简单易懂。
假设你的原始表结构为:
| 分组id | 待转列字段 | 值字段 |
|---|---|---|
| 1 | 类别1 | 数值1 |
| 1 | 类别2 | 数值2 |
| 2 | 类别1 | 数值3 |
| 2 | 类别2 | 数值4 |
转换语句参考:
SELECT 分组id, MAX(CASE WHEN 待转列字段 = '类别1' THEN 值字段 END) AS 类别1, MAX(CASE WHEN 待转列字段 = '类别2' THEN 值字段 END) AS 类别2 -- 有多少个要转的类别就加多少行上面的语句 FROM 你的表名 GROUP BY 分组id ORDER BY 分组id;
- 聚合函数用
MAX/MIN/SUM都可以,只要匹配你的值字段类型即可,作用是把多行的结果合并到同一行 - 如果要转换的列不固定,可结合动态SQL拼接生成查询语句
方案2:crosstab函数(固定列场景下写法更简洁)
需要先开启内置的tablefunc扩展:
CREATE EXTENSION IF NOT EXISTS tablefunc;
转换语句参考:
SELECT * FROM crosstab( 'SELECT 分组id, 待转列字段, 值字段 FROM 你的表名 ORDER BY 1,2', 'SELECT DISTINCT 待转列字段 FROM 你的表名 ORDER BY 1' ) AS ct(分组id INT, 类别1 INT, 类别2 INT);
- 第一个参数返回的列必须严格按照「分组列、待转列、值列」的顺序排列
- 最后的AS部分要明确定义返回的所有列名和类型,需要和你要转换的列顺序、类型完全匹配
注意:如果要转换的列是动态不确定的,crosstab函数无法直接支持,仍需使用动态SQL实现。
内容的提问来源于stack exchange,提问作者NK1
相关产品推荐
相关产品推荐

