Teradata: рекурсивно вычитать - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть набор данных следующим образом:

Product  Customer  Sequence   Amount
A        123       1          928.69
A        123       2          5032.81
A        123       3          6499.19
A        123       4          7908.57

Я хочу рекурсивно вычесть суммы, основанные на результате предыдущего вычитания (сохраняя первую сумму как есть), в столбце «Результат»

например. Вычтите 0 из 928,69 = 928,69, вычтите 928,69 из 5032,81 = 4104,12, вычтите 4104,12 из 6499,19 = 2395,07 и т. Д. (Для каждого продукта / клиента)

Я пытаюсь достичь следующих результатов:

Product  Customer  Sequence  Amount    Result
A        123       1         928.69    928.69
A        123       2         5032.81   4104.12
A        123       3         6499.19   2395.07
A        123       4         7908.57   5513.50

Я пытался добиться этого, используя комбинации LEAD и LAG, но не мог понять, как использовать результат в следующей строке.

Я думаю, что возможно использовать рекурсивное утверждение, повторяющееся по последовательности, однако я не знаком с рекурсией teradata и не смог успешно адаптировать найденные мной сэмплы.

Может кто-нибудь подсказать мне, как отформатировать рекурсивный оператор SQL teradata для достижения вышеуказанного результата? Я также открыт для нерекурсивных опций, если они есть.

CREATE VOLATILE TABLE MY_TEST (Product CHAR(1), Customer INTEGER, Sequence INTEGER, Amount DECIMAL(16,2)) ON COMMIT PRESERVE ROWS;
INSERT INTO MY_TEST VALUES ('A', 123, 1, 928.69);
INSERT INTO MY_TEST VALUES ('A', 123, 2, 5032.81);
INSERT INTO MY_TEST VALUES ('A', 123, 3, 6499.19);
INSERT INTO MY_TEST VALUES ('A', 123, 4, 7908.57);

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Это действительно странно из-за чередования + и -.

Если вы знаете, что значение всегда положительное, то это работает:

with t as (
      select 1 as customer, 928.69 as amount,  928.69 as result union all
      select 2, 5032.81, 4104.12 union all
      select 3, 6499.19, 2395.07 union all
      select 4, 7908.57, 5513.50 
    )
select t.*,
       abs(sum( case when seqnum mod 2 = 1 then - amount else amount end ) over (partition by product order by sequence rows unbounded preceding)
from t;

abs() действительно ярлык. Если полученное значение может быть отрицательным, вы можете использовать внешнее выражение case, чтобы определить, следует ли умножить результат на -1 или 1:

select t.*,
       ((case when sequence mod 2 = 1 then -1 else 1 end) *
        sum( case when sequence mod 2 = 1 then - amount else amount end ) over (partition by product order by sequence  rows unbounded preceding)
       )
from t
0 голосов
/ 15 ноября 2018
select colA-der_col_A from table A,
(select coalesce(min(col_A) as der_col_A over (partition by col_B  order by col_A rows between 1 following and 1 following), 0)
from table) B
on (A.col_b=B.Col_B);

Замените col_A и col_B вашими ключевыми столбцами. Продукт, клиент и последовательность в вашем случае.

...