利用Oracle UnPivot 实现自定义的行转列
Contents
以下是测试数据
create table Fruit
(id int,name varchar(20),
Q1 int, Q2 int,
Q3 int, Q4 int);
insert into Fruit values(1,'苹果',1000,2000,3300,5000);
insert into Fruit values(2,'橘子',3000,3000,3200,1500);
insert into Fruit values(3,'香蕉',2500,3500,2200,2500);
insert into Fruit values(4,'葡萄',1500,2500,1200,3500);
需求一:将Q1,Q2,Q3和Q4转成列模式
SELECT * FROM FRUIT UNPIVOT
(SALE FOR QUATER IN (Q1, Q2, Q3, Q4));
其中"Q1,Q2,Q3,Q4" 是表中现有的列名,所谓列传行就是将多列合并成一列,合并后的列名就是QUATER(此列名可以根据自己的喜好自定义)
SALE对应的是新列(QUATER)的值(类似于Key-Value的格式)
查询结果如下:
ID | Name | SALE | QUATER |
---|---|---|---|
1 | 苹果 | 1000 | Q1 |
1 | 苹果 | 2000 | Q2 |
1 | 苹果 | 3300 | Q3 |
1 | 苹果 | 5000 | Q4 |
2 | 橘子 | 3000 | Q1 |
2 | 橘子 | 3000 | Q2 |
2 | 橘子 | 3200 | Q3 |
2 | 橘子 | 1500 | Q4 |
3 | 香蕉 | 2500 | Q1 |
3 | 香蕉 | 3500 | Q2 |
3 | 香蕉 | 2200 | Q3 |
3 | 香蕉 | 2500 | Q4 |
4 | 葡萄 | 1500 | Q1 |
4 | 葡萄 | 2500 | Q2 |
4 | 葡萄 | 1200 | Q3 |
4 | 葡萄 | 3500 | Q4 |
以上是基本的行转列,随便一搜会有很多例子,结果是一行数据生成四条行数据,现在有一个比较奇葩的需求,需要自定义行转列,要把Q2和Q2当做一个整体,Q3和Q4当做一个整体。结果是一行数据生成两行数据。
经过研究Oracle提供的语法图,利用括号将两列合并成一列
SELECT * FROM FRUIT t
UNPIVOT((SALE1,SALE2) FOR QUATER IN
((Q1, Q2), (Q3, Q4)));
查询结果
ID | Name | SALE1 | SALE2 | QUATER |
---|---|---|---|---|
1 | 苹果 | 1000 | 2000 | Q1_Q2 |
1 | 苹果 | 3300 | 5000 | Q3_Q4 |
2 | 橘子 | 3000 | 3000 | Q1_Q2 |
2 | 橘子 | 3200 | 1500 | Q3_Q4 |
3 | 香蕉 | 2500 | 3500 | Q1_Q2 |
3 | 香蕉 | 2200 | 2500 | Q3_Q4 |
4 | 葡萄 | 1500 | 2500 | Q1_Q2 |
4 | 葡萄 | 1200 | 3500 | Q3_Q4 |
由于是一行生成了两行对于的Key不再是Q3,Q2,Q3和Q4而是Q1_Q2和Q3_Q4