Featured image of post DuckDB 长宽表转换完全指南:PIVOT/UNPIVOT 一篇通关

DuckDB 长宽表转换完全指南:PIVOT/UNPIVOT 一篇通关

DuckDB 原生 PIVOT/UNPIVOT 语法详解:告别 Python Pandas 繁琐代码,一条 SQL 完成长宽表转换,性能超越 Pandas 10 倍+

引言:一个每天都在发生的痛点

你是否遇到过这样的场景:业务方跑过来要一份报表,数据源是"长表"格式——每一行是一条记录,渠道、月份、金额各占一列。但领导要看的是"宽表"——月份为行,各渠道为列,一眼对比清楚。

在过去,这需要 Python + Pandas:写 pivot()groupby().unstack(),处理缺失值,调试索引……一套流程下来,半小时起步。

今天我们来聊聊 DuckDB 的原生 PIVOT/UNPIVOT 语法。一条 SQL 搞定,零依赖,性能还比 Pandas 快 10 倍以上。


一、PIVOT:长表转宽表

1.1 基础语法

DuckDB 的 PIVOT 语法非常直观:

PIVOT table_name
ON pivot_column
USING aggregate_function(value_column)
GROUP BY group_columns;

1.2 完整实战示例

假设你有以下销售数据(长表格式):

| month  | channel | amount |
|--------|---------|--------|
| 2026-01 | 天猫     | 150000 |
| 2026-01 | 京东     | 98000  |
| 2026-01 | 抖音     | 220000 |
| 2026-02 | 天猫     | 180000 |
| 2026-02 | 京东     | 110000 |
| 2026-02 | 抖音     | 195000 |
| 2026-03 | 天猫     | 205000 |
| 2026-03 | 京东     | 125000 |
| 2026-03 | 抖音     | 240000 |

一条 SQL 转换为宽表:

PIVOT sales
ON channel
USING SUM(amount)
GROUP BY month;

输出结果:

| month  |  天猫  |  京东  |  抖音  |
|--------|--------|--------|--------|
| 2026-01 | 150000 |  98000 | 220000 |
| 2026-02 | 180000 | 110000 | 195000 |
| 2026-03 | 205000 | 125000 | 240000 |

1.3 Python 完整代码

import duckdb

con = duckdb.ATTACH ("ecommerce.db")

# 创建测试数据
con.execute("""
---

## 本文信息

| 项目 | 内容 |
|------|------|
| DuckDB 版本 | v1.5.x(部分功能基于 v2.0 Preview) |
| 最后验证 | 2026-09-12 |
| 测试环境 | Linux / x86_64 / 16GB RAM |
| 官方文档 | [DuckDB Documentation](https://duckdb.org/docs/) |
| GitHub | [pengzz9527/duckdb-blog](https://github.com/pengzz9527/duckdb-blog) |

如发现错误,欢迎通过 [GitHub Issue](https://github.com/pengzz9527/duckdb-blog/issues) 或邮件 [email protected] 反馈。

📺 Watch video tutorials → Olap Studio YouTube

Subscribe for more DuckDB & AI automation tutorials

使用 Hugo 构建
主题 StackJimmy 设计