如何用SQL Pivot将Quantity与Net列合并为Account和Value列?
实现SQL表的逆透视(Unpivot)操作
你需要的是**逆透视(Unpivot)**操作(注意:Pivot是行转列,这里是列转行,属于逆透视),将Quantity和Net列转换为Account(列名)和Value(对应值)的行维度对,以下是几种不同场景的实现方案:
原表结构与数据
| Location | Type | Date | Quantity | Net |
|---|---|---|---|---|
| A1 | Base | 25-Jan | 10 | 40 |
| A1 | Premium | 25-Jan | 5 | 30 |
| A2 | Premium | 26-Jan | 3 | 18 |
| B1 | Base | 27-Jan | 4 | 16 |
| B2 | Base | 24-Jan | 8 | 32 |
| B2 | Premium | 25-Jan | 2 | 12 |
目标表结构与数据
| Location | Type | Date | Account | Value |
|---|---|---|---|---|
| A1 | Base | 25-Jan | Net | 40 |
| A1 | Base | 25-Jan | Quantity | 10 |
| A1 | Premium | 25-Jan | Net | 30 |
| A1 | Premium | 25-Jan | Quantity | 5 |
| A2 | Premium | 26-Jan | Net | 18 |
| A2 | Premium | 26-Jan | Quantity | 3 |
| B1 | Base | 27-Jan | Net | 16 |
| B1 | Base | 27-Jan | Quantity | 4 |
| B2 | Base | 24-Jan | Net | 32 |
| B2 | Base | 24-Jan | Quantity | 8 |
| B2 | Premium | 25-Jan | Net | 12 |
| B2 | Premium | 25-Jan | Quantity | 2 |
方法1:通用UNION ALL实现(全数据库兼容)
这是兼容性最强的方案,适用于所有支持UNION ALL的SQL数据库:
SELECT Location, Type, Date, 'Net' AS Account, Net AS Value FROM your_table_name UNION ALL SELECT Location, Type, Date, 'Quantity' AS Account, Quantity AS Value FROM your_table_name ORDER BY Location, Type, Date, Account DESC; -- 排序用于匹配目标表顺序,可按需调整
- 逻辑:分别提取
Net和Quantity列的数据,将列名作为Account值,列值作为Value,再合并结果集。
方法2:UNPIVOT语法实现(SQL Server、Oracle等支持的数据库)
如果你的数据库支持原生UNPIVOT关键字,可用更简洁的语法:
SELECT Location, Type, Date, Account, Value FROM your_table_name UNPIVOT ( Value FOR Account IN (Net, Quantity) ) AS unpivoted_data ORDER BY Location, Type, Date, Account DESC;
- 逻辑:通过
UNPIVOT子句直接指定要转换的列(Net、Quantity),自动生成Account(列名)和Value(列值)字段。
方法3:PostgreSQL专属实现
PostgreSQL无原生UNPIVOT,可通过LATERAL JOIN或ARRAY+UNNEST实现,推荐更清晰的LATERAL JOIN方式:
SELECT t.Location, t.Type, t.Date, u.Account, u.Value FROM your_table_name t LATERAL ( VALUES ('Net', t.Net), ('Quantity', t.Quantity) ) u(Account, Value) ORDER BY Location, Type, Date, Account DESC;
内容的提问来源于stack exchange,提问作者CraigA
相关产品推荐
相关产品推荐

