暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 如何对pivot查询结果进行求和

ASKTOM 2020-03-13
985

问题描述

with t1 as (select 'dfu1' dfu, 1 type, '01-Jan-2020' startdt, 10 period1, 20 period2, 30 period3, null period4, 50 period5 from dual 
union all 
select 'dfu1' dfu, 4 type, '01-Jan-2020' startdt, 1 period1, 2 period2, 3 period3, 4 period4, null period5 from dual 
union all 
select 'dfu1' dfu, 6 type, '01-Jan-2020' startdt, 1 period1, 1 period2, 1 period3, 1 period4, 1 period5 from dual 
union all 
select 'dfu2' dfu, 1 type, '01-Jan-2020' startdt, 40 period1, 50 period2, null period3, null period4, 50 period5 from dual 
union all 
select 'dfu2' dfu, 4 type, '02-Jan-2020' startdt, 1 period1, 2 period2, null period3, 4 period4, 5 period5 from dual 
union all 
select 'dfu2' dfu, 6 type, '03-Jan-2020' startdt, 1 period1, 1 period2, 1 period3, 1 period4, 1 period5 from dual) 
select * from t1
复制



DFU TYPE STARTDT PERIOD1 PERIOD2 PERIOD3 PERIOD4 PERIOD5
dfu1 1 01-Jan-2020 10 20 30 - 50
dfu1 4 01-Jan-2020 1 2 3 4 -
dfu1 6 01-Jan-2020 1 1 1 1 1
dfu2 1 01-Jan-2020 40 50 - - 50
dfu2 4 02-Jan-2020 1 2 - 4 5
dfu2 6 03-Jan-2020 1 1 1 1 1
复制


如果我拿一个dfu1 -> 它有三个记录type1,type4,type6

对于到达类型记录-> 4期的数量,期1,期2,期3,期4

基于startdt列,对于dfu1:type1:period1表示01-1月-2020的数量,
对于dfu1: 类型1:period2表示01-1月-2020 1 -> 的数量,即02-1月-2020,
对于dfu1: 类型1:period3表示01-1月-2020 2 -> 的数量,即03-1月-2020,
对于dfu1: 类型1:period4表示01-1月-2020 3 -> 的数量,即04-1月-2020

等等...对于dfu1: 4型,dfu1: 6型

现在对于dfu1 -> 我想按类型获取一个总和 (数量) 组,

这可以很容易地实现,因为dfu1的startdate对于所有三种类型都是相同的。

而对于dfu2

type1、type4和type6有三个不同的开始日期。

所以我们不能只求和 (period1) 来获得period1值。

对于dfu2:type1 -> 基于startdt列指示01-1月-2020的数量,对于类型4和类型6,对于01-1月-2020没有值,因为类型4和类型6从02-1月-2020和03-1月-2020开始
所以dfu2周期1的总和只有40

对于dfu2 -> period2值为02-1月-2020,应计算为总和 (dfu2: 类型1:PERIOD2,dfu2: 类型4:PERIOD1) 对于02-1月-2020没有dfu2: 类型6的值

对于dfu2 -> period3值应为SUM (类型1:PERIOD3,类型2:PERIOD2,类型3:PERIOD1)
对于dfu2 -> period4值应为SUM (类型1:PERIOD4,类型2:PERIOD3,类型3:PERIOD2)
对于dfu2 -> period5值应为SUM (类型1:PERIOD5,类型2:PERIOD4,类型3:PERIOD3)

等等...

DFU STARTDT PERIOD1 PERIOD2 PERIOD3 PERIOD4 PERIOD5
dfu1 1-Jan-20 12 23 34 5 51      
dfu2 1-Jan-20 40 51 3 1 55
复制


考虑因素,

开始日期应该最小 (开始日期)
如果一个周期没有值,则应视为零。


我能够通过unpivot查询获得输出,但是要查看是否有可能在没有unpivot的情况下实现输出,就像我的情况一样,是unpivot,再次进行求和和pivot


专家解答

我对这里到底发生了什么感到困惑。感觉表格混合了行和列值...向我们展示您的枢轴/取消枢轴解决方案会有所帮助!

无论如何,要获得给定显示的数据要求的输出,您可以:

-通过dfu & startdt总结值
-使用潜在客户期待每个时期的下一个值

这给出了以下相当复杂的查询:

with t1 as (
  select 'dfu1' dfu, 1 type, '01-Jan-2020' startdt, 10 period1, 20 period2, 30 period3, 0 period4, 50 period5 from dual 
  union all 
  select 'dfu1' dfu, 4 type, '01-Jan-2020' startdt, 1 period1, 2 period2, 3 period3, 4 period4, 0 period5 from dual 
  union all 
  select 'dfu1' dfu, 6 type, '01-Jan-2020' startdt, 1 period1, 1 period2, 1 period3, 1 period4, 1 period5 from dual 
  union all 
  select 'dfu2' dfu, 1 type, '01-Jan-2020' startdt, 40 period1, 50 period2, 0 period3, 0 period4, 50 period5 from dual 
  union all 
  select 'dfu2' dfu, 4 type, '02-Jan-2020' startdt, 1 period1, 2 period2, 0 period3, 4 period4, 5 period5 from dual 
  union all 
  select 'dfu2' dfu, 6 type, '03-Jan-2020' startdt, 1 period1, 1 period2, 1 period3, 1 period4, 1 period5 from dual
), rws as (
  select dfu, startdt, 
         sum ( period1 ) period1, 
         sum ( period2 ) period2, 
         sum ( period3 ) period3, 
         sum ( period4 ) period4, 
         sum ( period5 ) period5
  from   t1
  group  by dfu, startdt
), tots as (
  select dfu, startdt,
         period1 p1,
         period2 + lead ( 
           period1, 1, 0
         ) over (
           partition by dfu
           order by startdt
         ) p2,
         period3 + lead ( 
           period2, 1, 0
         ) over (
           partition by dfu
           order by startdt
         )  + lead ( 
           period1, 2, 0
         ) over (
           partition by dfu
           order by startdt
         ) p3,
         period4 + lead ( 
           period3, 1, 0
         ) over (
           partition by dfu
           order by startdt
         )  + lead ( 
           period2, 2, 0
         ) over (
           partition by dfu
           order by startdt
         ) p4,
         period5 + lead ( 
           period4, 1, 0
         ) over (
           partition by dfu
           order by startdt
         )  + lead ( 
           period3, 2, 0
         ) over (
           partition by dfu
           order by startdt
         ) p5,
         min ( startdt ) over (
           partition by dfu
         ) mn_dt
  from   rws
)
  select * from tots
  where  startdt = mn_dt;
  
DFU     STARTDT        P1    P2    P3    P4    P5    MN_DT         
dfu1    01-Jan-2020       12    23    34     5    51 01-Jan-2020    
dfu2    01-Jan-2020       40    51     3     1    55 01-Jan-2020  
复制


我不相信这个解决方案满足业务要求 (无论是什么)。而且我敢肯定,它比您拥有的pivot/unpivot方法更复杂。

给我们更多的背景知识,我们也许可以提供更好的帮助。
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论