У меня есть финансовые данные, хранящиеся в виде значений YTD за месяц, и я хотел бы написать запрос / представление, чтобы они имели периодические значения.

Пример исходной таблицы:

enter image description here

Оглядываясь вокруг, я нашел способ, поворачивая 2 периода с начала года и делая их разницу для каждого периодического значения отдельно.

Ниже приведен пример расчета периодического значения за февраль 2018 года (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 ожидаемый результат: введите описание изображения здесь

Время стола введите описание изображения здесь

0
Wim F 20 Авг 2018 в 11:32

3 ответа

Лучший ответ

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 - один из столбцов или все из них? Но идея гораздо проще - соединение между временами, которые вы хотите сравнить.

1
Gordon Linoff 20 Авг 2018 в 11:15

Вы можете использовать динамический SQL (подробности см. Здесь: https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-executesql-transact-sql?view = SQL- сервер 2017 )

-1
brak_danych 20 Авг 2018 в 08:48

Исходя из данных примера и ожидаемого результата, вы, кажется, хотите рассчитать с предыдущим значением, поэтому вам не нужно использовать сводку, вы можете попробовать использовать 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

Результаты .

| 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
D-Shih 20 Авг 2018 в 09:29
51926862