使用 sql 将行转换为列,反之亦然 - oracle
Transform row into column and vice-versa using sql - oracle
我有这个table:
create table history (
date_check DATE,
type VARCHAR2(30),
id_type NUMBER,
total NUMBER
)
正在选择......
select * from history order by 1
DATE_CHECK TYPE ID_TYPE TOTAL
14/02/2016 abc 1 14
14/02/2016 abc33 1 14
14/02/2016 bbb 1 40
14/02/2016 bbb33 3 43
14/02/2016 ddd 2 61
14/02/2016 ddd33 2 62
15/02/2016 abc 1 33
15/02/2016 abc33 1 44
15/02/2016 bbb 1 55
15/02/2016 bbb33 3 66
15/02/2016 ddd 2 77
15/02/2016 ddd33 2 88
始终键入这 6 个值:
abc
abc33
bbb
bbb33
ddd
ddd33
然后我将这些数据与 "id_type" 交叉,所以有这样的解码:
select type || decode(id_type, 1, '- new', 2, '- old', 3, '- xpto') as type from history order by 1
最后我需要这样的东西:
DATE_CHECK abc - new abc33 - old bbb - new bbb33 - old ....
14/02/2016 14 14 40 43
15/02/2016 33 44 55 66
最简单的方法是什么?使用枢轴?
试试这个:
with data as(
select date_check, type, total from (
select date_check, type || ' ' || decode(id_type, 1, '- new', 2, '- old', 3, '- xpto') as type, total from history
))
select * from data
pivot(
max(total) for type in ('abc - new', 'abc33 - new', 'bbb - new',
'bbb33 - xpto', 'ddd - old', 'ddd33 - old')
)
order by date_check;
对于 "vice versa" 使用 UNPIVOT
您可以在数据透视表中引用多个列以获得所需的输出。在您的情况下,您有一个分析列 (TOTAL),但多个列形成复合列以在其上执行分析功能,您可以使用如下所示的数据透视查询:
select *
from history
PIVOT ( max(TOTAL)
for (TYPE, ID_TYPE) in ( ('abc',1) abc_new
, ('abc',2) abc_old
, ('abc',3) abc_xpto
, ('abc33',1) abc33_new
, ('abc33',2) abc33_old
, ('abc33',3) abc33_xpto
, ('bbb',1) bbb_new
, ('bbb',2) bbb_old
, ('bbb',3) bbb_xpto
, ('bbb33',1) bbb33_new
, ('bbb33',2) bbb33_old
, ('bbb33',3) bbb33_xpto
, ('ddd',1) ddd_new
, ('ddd',2) ddd_old
, ('ddd',3) ddd_xpto
, ('ddd33',1) ddd33_new
, ('ddd33',2) ddd33_old
, ('ddd33',3) ddd33_xpto
)
)
如果需要,您可以将输出列标题调整为套件,方法如下:
...
PIVOT ( max(TOTAL)
for (TYPE, ID_TYPE) in ( ('abc',1) "abc - new"
, ('abc',2) "abc - old"
, ('abc',3) "abc - xpto"
, ('abc33',1) "abc33 - new"
, ...
我有这个table:
create table history (
date_check DATE,
type VARCHAR2(30),
id_type NUMBER,
total NUMBER
)
正在选择......
select * from history order by 1
DATE_CHECK TYPE ID_TYPE TOTAL
14/02/2016 abc 1 14
14/02/2016 abc33 1 14
14/02/2016 bbb 1 40
14/02/2016 bbb33 3 43
14/02/2016 ddd 2 61
14/02/2016 ddd33 2 62
15/02/2016 abc 1 33
15/02/2016 abc33 1 44
15/02/2016 bbb 1 55
15/02/2016 bbb33 3 66
15/02/2016 ddd 2 77
15/02/2016 ddd33 2 88
始终键入这 6 个值:
abc
abc33
bbb
bbb33
ddd
ddd33
然后我将这些数据与 "id_type" 交叉,所以有这样的解码:
select type || decode(id_type, 1, '- new', 2, '- old', 3, '- xpto') as type from history order by 1
最后我需要这样的东西:
DATE_CHECK abc - new abc33 - old bbb - new bbb33 - old ....
14/02/2016 14 14 40 43
15/02/2016 33 44 55 66
最简单的方法是什么?使用枢轴?
试试这个:
with data as(
select date_check, type, total from (
select date_check, type || ' ' || decode(id_type, 1, '- new', 2, '- old', 3, '- xpto') as type, total from history
))
select * from data
pivot(
max(total) for type in ('abc - new', 'abc33 - new', 'bbb - new',
'bbb33 - xpto', 'ddd - old', 'ddd33 - old')
)
order by date_check;
对于 "vice versa" 使用 UNPIVOT
您可以在数据透视表中引用多个列以获得所需的输出。在您的情况下,您有一个分析列 (TOTAL),但多个列形成复合列以在其上执行分析功能,您可以使用如下所示的数据透视查询:
select *
from history
PIVOT ( max(TOTAL)
for (TYPE, ID_TYPE) in ( ('abc',1) abc_new
, ('abc',2) abc_old
, ('abc',3) abc_xpto
, ('abc33',1) abc33_new
, ('abc33',2) abc33_old
, ('abc33',3) abc33_xpto
, ('bbb',1) bbb_new
, ('bbb',2) bbb_old
, ('bbb',3) bbb_xpto
, ('bbb33',1) bbb33_new
, ('bbb33',2) bbb33_old
, ('bbb33',3) bbb33_xpto
, ('ddd',1) ddd_new
, ('ddd',2) ddd_old
, ('ddd',3) ddd_xpto
, ('ddd33',1) ddd33_new
, ('ddd33',2) ddd33_old
, ('ddd33',3) ddd33_xpto
)
)
如果需要,您可以将输出列标题调整为套件,方法如下:
...
PIVOT ( max(TOTAL)
for (TYPE, ID_TYPE) in ( ('abc',1) "abc - new"
, ('abc',2) "abc - old"
, ('abc',3) "abc - xpto"
, ('abc33',1) "abc33 - new"
, ...