我有一个包含以下simplfied结构的表: 平衡,日期,credit_type。 根据日期和信用类型(每日负载),我需要预测余额的未来流量。 还需要考虑周末和假期, 有什么想法吗?
以下是一些示例数据:
data table
balance_actual partner credit_type date
12000 C&A CRD_type_1 25-08-2015
Rule Table
credit_type No_Of_Installments days_due_1st_Installment next_install_days
CRD_type_1 2 3 4
以下是所需的结果集:
balance_forecast partner credit_type date
6000 C&A CRD_type_1 26-08-2015
6000 C&A CRD_type_1 27-08-2015
0 C&A CRD_type_1 28-08-2015
6000 C&A CRD_type_1 29-08-2015
6000 C&A CRD_type_1 30-08-2015
6000 C&A CRD_type_1 31-08-2015
0 C&A CRD_type_1 01-09-2015
所需的balance_forecast = balance_actual / No_Of_Installments。 在2015年8月28日,我的balance_forecast为零,因为days_due_1st_Installment = 3(初始日期后3天)。同样的日期01-09-2015再次归零,因为next_install_day = 4(第一个分期付款日期后4天)。
答案 0 :(得分:0)
有几个小问题需要解决。
有几种方法可以解决它们。 MODEL子句是一个选项,但这非常粗糙。使用一系列子查询更加冗长,但更容易看到发生了什么。
第一个子查询将LOAN详细信息与其RULE连接起来,并计算贷款的生命周期和每个分期付款的大小。
with lr as ( select l.balance_actual
, l.start_date
, l.partner
, l.credit_type
, r.days_due_1st_Installment
+ (r.next_install_days * (r.No_Of_Installments-1)) tot_days
, (l.balance_actual/r.No_Of_Installments) installment
, r.days_due_1st_Installment
, r.next_install_days
, r.No_Of_Installments
from loan l
join rule r
on l.credit_type = r.credit_type
)
第二个子查询获取该输出并计算每笔贷款到期的日期,使用CONNECT BY技巧生成一组行:
, sch as (
select case when level = 1 then lr.start_date + lr.days_due_1st_Installment
else lr.start_date + lr.days_due_1st_Installment
+ (lr.next_install_days * (level-1))
end as due_date
, lr.*
from lr
connect by level <= lr.No_Of_Installments
)
第三个子查询再次使用CONNECT BY技巧生成日期列表:
, pln as ( select lr.start_date + level as cal_date
from lr
connect by level <= lr.tot_days
)
主查询使用令人兴奋的连接类型数组连接这些子查询,并使用Analytic SUM()函数计算剩余余额:
select pln.cal_date
, sch.installment as install_due
, lr.balance_actual - nvl((sum(sch.installment)
over (order by pln.cal_date)),0) as forecast_balance
, lr.credit_type
, lr.partner
from lr
cross join pln
left join sch on sch.due_date = pln.cal_date
order by pln.cal_date
;
请注意,我对FORECAST_BUDGET的计算与发布的计算不同。我认为我的实施更有意义,但OP可能不同意:)
所以,这就是整个事情:
with lr as
( select l.balance_actual
, l.start_date
, l.partner
, l.credit_type
, r.days_due_1st_Installment + (r.next_install_days * (r.No_Of_Installments-1)) tot_days
, (l.balance_actual/r.No_Of_Installments) installment
, r.days_due_1st_Installment
, r.next_install_days
, r.No_Of_Installments
from loan l
join rule r
on l.credit_type = r.credit_type
)
, sch as (
select case when level = 1 then lr.start_date + lr.days_due_1st_Installment
else lr.start_date + lr.days_due_1st_Installment + (lr.next_install_days * (level-1))
end as due_date
, lr.*
from lr
connect by level <= lr.No_Of_Installments
)
, pln as ( select lr.start_date + level as cal_date
from lr
connect by level <= lr.tot_days
)
select pln.cal_date
, sch.installment as install_due
, lr.balance_actual - nvl((sum(sch.installment) over (order by pln.cal_date)),0) as forecast_balance
, lr.credit_type
, lr.partner
from lr
cross join pln
left join sch on sch.due_date = pln.cal_date
order by pln.cal_date
日期计算都没有考虑假期或周末。那是因为OP没有说明他们想要的东西,尽管我们可以猜测(即分期和到期日仅为工作日)。
Oracle没有为假期提供内置解决方案。因此,应用程序必须以自己的方式处理它们。
周末是有问题的,因为它们是由NLS参数定义的(是你周的第1天或第7天?哪些日子包括周末?)。 Other SO threads tackle this