sql 查询:数据透视表但计数或行数不同

sql query: pivot but with different count or rows

构建查询以将行收集到像数据透视表这样的列中但没有聚合并且每列中可能有几行的最佳变体是什么?

示例数据:

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

每个月可能包含不同的行数。我必须将它们放在一起并按高度证明其合理性。 我想将这些数据显示为:

parent_fk, jan, feb, mar
1111,    21, 12, __
1111,    24, __, __
2222,     3,  4,  5
3333,    __, 77, 99
3333,    __, 88, __

目前我有这样的查询(在每个月内创建排序 row_number 在分区上,并通过此排序加入所有月):

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,因为我不知道哪个月包含最大行数,而所有其他月在那里都为空)。

在 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