Snowflake 中的交叉引用列 SQL
Cross-referecing columns in Snowflake SQL
我正在尝试使用 Snowflake-SQL 建立摊销计划,但是我需要两列相互引用才能计算活动价值和现值。在 excel 中,它将是这样的:
在 SQL 中,我尝试这样做但它不起作用:
,LAG(present_value) OVER (PARTITION BY ti.request_id ORDER BY ti.reference_date) AS active_value
,active_value - c.installment_amount AS present_value
我如何能够在 SQL 中复制我使用 excel 所做的事情?
所以种子数据的 CTE 很糟糕:
with data(y,start_date, amount, interest_y_c4, payment_c9, interest_d_c4_p1) as (
select *
,(0.0007223821155291760::double) + 1.00::double
from values
(1,'2021-11-10', 1690.96::double, 0.263669472168149::double, 304.90::double)
), payment_days(x,days, acc_days) as (
select *
,sum(column2) over(order by column1)
from values
(1, 0),
(2, 28),
(3, 35),
(4, 28),
(5, 24),
(6, 31),
(7, 30)
), rc as (
和递归 CTE 这可以解决:
with RECURSIVE rec_cte as (
select
d.y,
pd.x + 1 as x,
pd.days,
dateadd('days',pd.acc_days, d.start_date)::date as payment_date,
d.amount as active_value,
0.0::double as interest,
d.amount as present_value
from data as d
join payment_days as pd
on pd.x = 1
UNION ALL
select
d.y,
pd.x + 1 as x,
pd.days,
dateadd('days',pd.acc_days, d.start_date)::date as payment_date,
round(r.present_value * pow(d.interest_d_c4_p1, pd.days),10) as _active_value,
(_active_value - r.present_value) as interest,
greatest(0, _active_value - d.payment_c9) as present_value
from rec_cte as r
join data as d
on r.y = d.y
join payment_days as pd
on r.x = pd.x
)
select y as customer_id
,days
,payment_date
,floor(active_value,2) as active_value
,floor(interest,2) as interest
,floor(present_value,2) as present_value
from rec_cte
给予:
CUSTOMER_ID
DAYS
PAYMENT_DATE
ACTIVE_VALUE
INTEREST
PRESENT_VALUE
1
0
2021-11-10
1,690.96
0
1,690.96
1
28
2021-12-08
1,725.49
34.53
1,420.59
1
35
2022-01-12
1,456.96
36.36
1,152.06
1
28
2022-02-09
1,175.59
23.53
870.69
1
24
2022-03-05
885.91
15.22
581.01
1
31
2022-04-05
594.16
13.15
289.26
1
30
2022-05-05
295.6
6.33
0
我不是您每日利率或付款的 100%,所以解决这些问题花费了大部分时间。所以接下来请把它们包括在内。
我也不会用 double
钱..但我第一次使用 number(20,10) 并不是那么成功..
我正在尝试使用 Snowflake-SQL 建立摊销计划,但是我需要两列相互引用才能计算活动价值和现值。在 excel 中,它将是这样的:
在 SQL 中,我尝试这样做但它不起作用:
,LAG(present_value) OVER (PARTITION BY ti.request_id ORDER BY ti.reference_date) AS active_value
,active_value - c.installment_amount AS present_value
我如何能够在 SQL 中复制我使用 excel 所做的事情?
所以种子数据的 CTE 很糟糕:
with data(y,start_date, amount, interest_y_c4, payment_c9, interest_d_c4_p1) as (
select *
,(0.0007223821155291760::double) + 1.00::double
from values
(1,'2021-11-10', 1690.96::double, 0.263669472168149::double, 304.90::double)
), payment_days(x,days, acc_days) as (
select *
,sum(column2) over(order by column1)
from values
(1, 0),
(2, 28),
(3, 35),
(4, 28),
(5, 24),
(6, 31),
(7, 30)
), rc as (
和递归 CTE 这可以解决:
with RECURSIVE rec_cte as (
select
d.y,
pd.x + 1 as x,
pd.days,
dateadd('days',pd.acc_days, d.start_date)::date as payment_date,
d.amount as active_value,
0.0::double as interest,
d.amount as present_value
from data as d
join payment_days as pd
on pd.x = 1
UNION ALL
select
d.y,
pd.x + 1 as x,
pd.days,
dateadd('days',pd.acc_days, d.start_date)::date as payment_date,
round(r.present_value * pow(d.interest_d_c4_p1, pd.days),10) as _active_value,
(_active_value - r.present_value) as interest,
greatest(0, _active_value - d.payment_c9) as present_value
from rec_cte as r
join data as d
on r.y = d.y
join payment_days as pd
on r.x = pd.x
)
select y as customer_id
,days
,payment_date
,floor(active_value,2) as active_value
,floor(interest,2) as interest
,floor(present_value,2) as present_value
from rec_cte
给予:
CUSTOMER_ID | DAYS | PAYMENT_DATE | ACTIVE_VALUE | INTEREST | PRESENT_VALUE |
---|---|---|---|---|---|
1 | 0 | 2021-11-10 | 1,690.96 | 0 | 1,690.96 |
1 | 28 | 2021-12-08 | 1,725.49 | 34.53 | 1,420.59 |
1 | 35 | 2022-01-12 | 1,456.96 | 36.36 | 1,152.06 |
1 | 28 | 2022-02-09 | 1,175.59 | 23.53 | 870.69 |
1 | 24 | 2022-03-05 | 885.91 | 15.22 | 581.01 |
1 | 31 | 2022-04-05 | 594.16 | 13.15 | 289.26 |
1 | 30 | 2022-05-05 | 295.6 | 6.33 | 0 |
我不是您每日利率或付款的 100%,所以解决这些问题花费了大部分时间。所以接下来请把它们包括在内。
我也不会用 double
钱..但我第一次使用 number(20,10) 并不是那么成功..