将YTD值转换为期间(无日期字段)

时间:2018-08-20 08:32:23

标签: sql sql-server tsql

我每月将财务数据存储为YTD值,并希望编写查询/视图以将其作为定期值。

样本源表:

enter image description here

环顾四周,我确实找到了一种方法,通过旋转2个YTD周期并分别为每个周期值分别设置它们的差值。

下面的示例是2018年2月(TIMEID 20180200)周期值的计算。

Select * FROM
(Select '2018_02' as PERIOD, CATEGORY,DATASRC,ENTITY,GROUPS,Subtables as CC,ACCOUNT, Coalesce(Ytd,0) - Coalesce(PrYtd,0) as MTD
FROM(
Select CATEGORY,DATASRC,ENTITY,GROUPS,SUBTABLES,ACCOUNT, [20180200] as Ytd, [20180100] as PrYtd
FROM 
(Select ACCOUNT,CATEGORY, DATASRC, ENTITY, Rezidor_5.dbo.tblFactFinance.INTCO, Sum(SIGNEDDATA) as Amount, SUBTABLES, GROUPS, TIMEID, CURRENCY
 From (Rezidor_5.dbo.tblFactFinance INNER JOIN Rezidor_5.dbo.mbrAccount ON Rezidor_5.dbo.tblFactFinance.ACCOUNT = Rezidor_5.dbo.mbrAccount.ID) INNER JOIN Rezidor_5.dbo.mbrEntity ON Rezidor_5.dbo.tblFactFINANCE.ENTITY = Rezidor_5.dbo.mbrEntity.ID
 WHERE  LEFT(TIMEID,4) = '2018' AND CATEGORY In ('ACTUAL') AND Rezidor_5.dbo.tblFactFinance.INTCO ='TPTOP' AND ACCTYPE in ('INC', 'EXP') AND ENTITY = 'EDIZR' AND DATASRC in ('INPUT','INPUT_LADJ') and GROUPS = 'LC'
GROUP BY ACCOUNT,CATEGORY, DATASRC, ENTITY, Rezidor_5.dbo.tblFactFinance.INTCO, SUBTABLES, GROUPS, TIMEID,CURRENCY) t1
PIVOT
(SUM(Amount) FOR TIMEID in ([20180100],[20180200])) as t2) as t3)as t4
WHERE MTD <> 0

我的问题是我想动态地执行此操作,避免对句点进行硬编码。我确实可以使用变量,但是发现了Pivot元素 无法处理变量。

更好的一种技巧是,我可以将其应用于整个桌子。

感谢任何可以使我走上正轨的输入。

@ D-Shih预期结果: enter image description here

上桌时间 enter image description here

3 个答案:

答案 0 :(得分:1)

根据样本数据和您希望使用先前的值进行计算的预期结果,因此您无需使用数据透视,可以尝试使用LAG来获取先前的值然后进行计算。

CREATE TABLE T(
   ACCOUNT varchar(50),
   CATEGORY varchar(50),
   DATASRC varchar(50),
   ENTITY varchar(50),
   INTCO varchar(50),
   SIGNEDDATA int,
   source int,
   SUBTABLES varchar(50),
   TIMEID varchar(50),
   GROUPS varchar(50)
);

insert into t values ('TDEC','ACTUAL','INPUT','BRUZT','TPTOP',100,0,'CA','20180100','EUR')
insert into t values ('TDEC','ACTUAL','INPUT','BRUZT','TPTOP',400,0,'CA','20180200','EUR')
insert into t values ('TDEC','ACTUAL','INPUT','BRUZT','TPTOP',600,0,'CA','20180300','EUR')

查询1

select 
    ACCOUNT,
    CATEGORY,
    DATASRC,
    ENTITY,
    INTCO,
    (SIGNEDDATA - LAG(SIGNEDDATA,1,0) OVER(PARTITION BY ACCOUNT,GROUPS ORDER BY TIMEID)) SIGNEDDATA,
    source,
    SUBTABLES,
    TIMEID,
    GROUPS
from T

Results

| ACCOUNT | CATEGORY | DATASRC | ENTITY | INTCO | SIGNEDDATA | source | SUBTABLES |   TIMEID | GROUPS |
|---------|----------|---------|--------|-------|------------|--------|-----------|----------|--------|
|    TDEC |   ACTUAL |   INPUT |  BRUZT | TPTOP |        100 |      0 |        CA | 20180100 |    EUR |
|    TDEC |   ACTUAL |   INPUT |  BRUZT | TPTOP |        300 |      0 |        CA | 20180200 |    EUR |
|    TDEC |   ACTUAL |   INPUT |  BRUZT | TPTOP |        200 |      0 |        CA | 20180300 |    EUR |

注意

您可以使用计算组列PARTITION BY并设置列 以order by

的顺序

答案 1 :(得分:1)

PIVOT在这里无济于事。只需使用JOIN并将值作为参数传递:

with t as (
      select ACCOUNT, CATEGORY, DATASRC, ENTITY,
             ff.INTCO, sum(SIGNEDDATA) as Amount, 
             SUBTABLES, GROUPS, TIMEID, CURRENCY
      from Rezidor_5.dbo.tblFactFinance ff INNER JOIN
           Rezidor_5.dbo.mbrAccount a
           ON ff.ACCOUNT = a.mbrAccount.ID INNER JOIN
           Rezidor_5.dbo.mbrEntity e
           ON ff.ENTITY = e.ID
     where CATEGORY In ('ACTUAL') AND
           ff.INTCO ='TPTOP' AND
           ACCTYPE in ('INC', 'EXP') AND
           ENTITY = 'EDIZR' AND
           DATASRC in ('INPUT','INPUT_LADJ') AND
           GROUPS = 'LC'
     group by timeid, ACCOUNT, CATEGORY, DATASRC, ENTITY,
              ff.INTCO, 
              SUBTABLES, GROUPS, TIMEID, CURRENCY
    )
select 
from (select t.*
      from t
      where timeid = @timeid1
     ) t1 full outer join
     (select t.*
      from t
      where timeid = @timeid2
     )
     on . . . ;

对于join条件应该是什么,我还是有点不清楚-是其中一列还是全部?但是这个想法要简单得多-您想要比较的时间之间的连接。

答案 2 :(得分:-1)