构造查询以将行收集到像pivot这样的列中的最佳变体是什么,但没有聚合,每列中可能有多行?
示例数据:
id, parent_fk, month, quantity
10, 1111, 'jan', 21
11, 1111, 'jan', 24
12, 1111, 'feb', 12
13, 2222, 'jan', 3
14, 2222, 'feb', 4
15, 2222, 'mar', 5
16, 3333, 'feb', 77
17, 3333, 'feb', 88
16, 3333, 'mar', 99
每个月可能包含不同的行数。我必须把它们放在一边,并由heigths证明。 我想将这些数据显示为:
parent_fk, jan, feb, mar
1111, 21, 12, __
1111, 24, __, __
2222, 3, 4, 5
3333, __, 77, 99
3333, __, 88, __
目前我有这样一个不优雅的查询(在每个月内使用row_number在分区上创建排序,并按此顺序加入所有monthes):
select
nvl(JAN.parent_fk, nvl(FEB.parent_fk, nvl(MAR.parent_fk, -1))) calc_parent_fk,
JAN.quantity jan,
FEB.quantity feb,
MAR.quantity mar
from
(select id, parent_fk, quantity,
row_number() OVER (PARTITION BY parent_fk, mnth order by id) "RN"
from T_MONTH_DATA
where mnth = 'jan') JAN
full join
(select id, parent_fk, quantity,
row_number() OVER (PARTITION BY parent_fk, mnth order by id) "RN"
from T_MONTH_DATA
where mnth = 'feb') FEB
on JAN.parent_fk = FEB.parent_fk and JAN.RN = FEB.RN
full join
(select id, parent_fk, quantity,
row_number() OVER (PARTITION BY parent_fk, mnth order by id) "RN"
from T_MONTH_DATA
where mnth = 'mar') MAR
on FEB.parent_fk = MAR.parent_fk and FEB.RN = MAR.RN
order by 1
是否有更简单的方式来呈现此类数据? 如何获得结果parent_fk? (我使用嵌套的NVL,因为我不知道哪个monthes包含最多行,而所有其他monthes都有null)。
答案 0 :(得分:2)
在Oracle 11g中使用pivot
子句和函数row_number()
,如下所示:
select parent_fk, jan, feb, mar
from (
select row_number() over (partition by mnth, parent_fk order by id) rn,
parent_fk, mnth, quantity
from t_month_data )
pivot (sum(quantity) for mnth in ('jan' jan, 'feb' feb, 'mar' mar))
order by parent_fk
测试数据和输出:
create table t_month_data (id number(4), parent_fk number(4),
mnth varchar2(3), quantity number(6));
insert into t_month_data values (10, 1111, 'jan', 21);
insert into t_month_data values (11, 1111, 'jan', 24);
insert into t_month_data values (12, 1111, 'feb', 12);
insert into t_month_data values (13, 2222, 'jan', 3);
insert into t_month_data values (14, 2222, 'feb', 4);
insert into t_month_data values (15, 2222, 'mar', 5);
insert into t_month_data values (16, 3333, 'feb', 77);
insert into t_month_data values (17, 3333, 'feb', 88);
insert into t_month_data values (16, 3333, 'mar', 99);
PARENT_FK JAN FEB MAR
--------- ---------- ---------- ----------
1111 21 12
1111 24
2222 3 4 5
3333 77 99
3333 88