Teradata:递归减去
Teradata: Recursively Subtract
我有一组数据如下:
Product Customer Sequence Amount
A 123 1 928.69
A 123 2 5032.81
A 123 3 6499.19
A 123 4 7908.57
我想做的是根据前一次减法的结果递归地减去金额(保持第一个金额不变),进入'Result'列
例如928.69减0 = 928.69,5032.81减928.69 = 4104.12,6499.19减4104.12 = 2395.07,等等(每个product/customer)
我想要达到的结果是:
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);
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 替换为您的密钥 columns.Product、客户和序列。
这真的很奇怪,因为 + 和 - 交替出现。
如果您知道该值始终为正,则此方法有效:
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
我有一组数据如下:
Product Customer Sequence Amount
A 123 1 928.69
A 123 2 5032.81
A 123 3 6499.19
A 123 4 7908.57
我想做的是根据前一次减法的结果递归地减去金额(保持第一个金额不变),进入'Result'列
例如928.69减0 = 928.69,5032.81减928.69 = 4104.12,6499.19减4104.12 = 2395.07,等等(每个product/customer)
我想要达到的结果是:
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);
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 替换为您的密钥 columns.Product、客户和序列。
这真的很奇怪,因为 + 和 - 交替出现。
如果您知道该值始终为正,则此方法有效:
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