Teradata:递归减去

时间:2018-11-15 10:48:40

标签: sql recursion teradata recursive-query

我有一组数据,如下所示:

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

我想做的是基于上一个减法的结果递归地减去金额(保持第一个金额不变)到“结果”列中

例如从928.69 = 928.69中减去0,从5032.81 = 4104.12中减去928.69,从6499.19 = 2395.07中减去4104.12,依此类推(对于每个产品/客户)

我想要达到的结果是:

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递归并不熟悉,因此无法成功地适应我发现的示例。

有人可以指导我如何格式化递归的Teradata SQL语句以实现上述结果吗?如果有的话,我也开放非递归选项。

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 :(得分:2)

这真的很奇怪,因为+和-交替出现。

如果您知道该值始终为正,则可以这样做:

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

答案 1 :(得分:0)

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替换为您的键列。根据情况选择产品,客户和顺序。