Oracle中如何使用UNPIVOT子句实现多列转置?
使用UNPIVOT子句转换宽表结构
假设你的原表名为your_table,结构和示例数据如下:
| order | code1 | value1 | code2 | value2 |
|---|---|---|---|---|
| 1 | A | 100 | B | 200 |
| 2 | C | 150 | D | 250 |
目标是将其转换为包含order、code、value三列的长表结构,以下是不同数据库中使用UNPIVOT的实现方式:
Oracle 实现
Oracle支持多列同时UNPIVOT,直接将成对的codeX/valueX列转换为行:
SELECT "order", code, value FROM your_table UNPIVOT ( (code, value) FOR pair IN ( (code1, value1) AS 'group1', (code2, value2) AS 'group2' ) );
这里的pair是临时分组标识,用于关联每一组code和value,最终结果中可以忽略该列。执行后得到的结果:
| order | code | value |
|---|---|---|
| 1 | A | 100 |
| 1 | B | 200 |
| 2 | C | 150 |
| 2 | D | 250 |
SQL Server 实现
SQL Server的UNPIVOT默认只支持单列转换,因此需要分别对code和value列进行UNPIVOT,再通过分组标识关联:
WITH code_cte AS ( SELECT [order], code, pair FROM your_table UNPIVOT ( code FOR pair IN (code1, code2) ) AS code_up ), value_cte AS ( SELECT [order], value, pair FROM your_table UNPIVOT ( value FOR pair IN (value1, value2) ) AS value_up ) SELECT c.[order], c.code, v.value FROM code_cte c JOIN value_cte v ON c.[order] = v.[order] AND c.pair = v.pair;
这里通过CTE分别拆解code和value列,利用pair(即原列名code1/code2、value1/value2)作为关联条件,最终得到目标结构。
注意事项
order是SQL关键字,因此需要用引号(Oracle)或方括号(SQL Server)包裹,避免语法错误。- 如果使用MySQL,由于其没有原生UNPIVOT支持,仍需使用
UNION ALL实现,写法如下(供参考):
SELECT `order`, code1 AS code, value1 AS value FROM your_table UNION ALL SELECT `order`, code2 AS code, value2 AS value FROM your_table;
内容的提问来源于stack exchange,提问作者Pato
相关产品推荐
相关产品推荐

