pg sql 列转行
时间: 2025-05-29 13:18:44 浏览: 19
### PostgreSQL 中实现列转行的方法
在 PostgreSQL 数据库中,虽然不像 Oracle 或 SQL Server 提供了内置的 `UNPIVOT` 函数,但仍可以通过其他方式实现列转行的功能。以下是常见的两种方法:
#### 方法一:使用 `UNION ALL`
通过手动编写多个 `SELECT` 查询并将它们的结果集组合在一起,可以模拟 `UNPIVOT` 的效果。
```sql
-- 原始表结构
CREATE TABLE sales (
year INT,
q1 INT,
q2 INT,
q3 INT,
q4 INT
);
INSERT INTO sales(year, q1, q2, q3, q4)
VALUES (2017, 12, 123, 324, 123),
(2018, 13, 455, 324, 878),
(2019, 29, 786, 473, 633);
-- 使用 UNION ALL 进行列转行
SELECT year, 'Q1' AS quarter, q1 AS amount FROM sales
UNION ALL
SELECT year, 'Q2', q2 FROM sales
UNION ALL
SELECT year, 'Q3', q3 FROM sales
UNION ALL
SELECT year, 'Q4', q4 FROM sales;
```
这种方法简单直观,适用于列数较少的情况[^1]。
---
#### 方法二:利用数组和 JSON 函数
PostgreSQL 支持强大的数组和 JSON 处理功能,这使得我们可以更灵活地完成列转行操作。
##### 示例代码:
```sql
-- 创建测试表并插入数据
CREATE TABLE sales (
year INT,
q1 INT,
q2 INT,
q3 INT,
q4 INT
);
INSERT INTO sales(year, q1, q2, q3, q4)
VALUES (2017, 12, 123, 324, 123),
(2018, 13, 455, 324, 878),
(2019, 29, 786, 473, 633);
-- 使用 JSONB_AGG 和 LATERAL 转换列到行
SELECT s.year, t.quarter, t.amount
FROM sales s,
LATERAL (
SELECT key AS quarter, value::int AS amount
FROM jsonb_each_text(to_jsonb(s) - 'year')
) t;
```
此方法的核心在于将每一行的数据转化为 JSON 对象,并提取键值对作为新的行记录[^3]。
---
#### 性能对比
- **`UNION ALL`** 方式适合静态场景下的少量列转换,易于理解和维护。
- **JSON/ARRAY** 方法更适合动态场景或未知数量的列情况,但可能带来额外的性能开销,尤其是在大数据量下[^4]。
---
### 注意事项
当涉及大量数据时,应考虑索引优化及查询计划分析,以确保执行效率满足需求。此外,在设计数据库模式时尽量减少需要频繁进行列转行的操作,因为这类变换通常意味着原始表的设计可能存在冗余或不规范化的问题[^2]。
阅读全文
相关推荐















