SQL Window 查找逾期天数的函数
SQL Window function to find days past due
我想从按日期排序的贷款列表中计算 DPD(逾期天数)。每个过去的到期日都应该重新计算。 参见附件中的示例。如何计算 "Days past due" 列?
出于某种原因,我将其视为 SQL 服务器。以下使用日期函数的 SQL 服务器约定。其他数据库也有类似的功能,但具体语法不同。
关键 ida -- 累积条件最大值 -- 没有改变:
select t.*,
(case when status = 'PastDue'
then datediff(date,
max(case when status <> 'PastDue' then dayDate end) over (partition by loadnumer order by daydate)
else 0
end) as daysPastDue
from t;
您想要计算 "past due" 的连续天数并在其间重置计数器。这是差距和孤岛问题。
如果日期总是增加 1 天,如示例数据所示,那么一种方法是取日期与 row_number()
之间的差异来定义每条记录所属的组。
你没有告诉你使用的是哪个数据库,所以这里有一个使用SQL服务器的dateadd()
进行日期计算的方法;不支持具有等效功能的数据库。
select
loan_number,
daydate,
status,
case when status = 'PastDue' then
count(*) over(
partition by loan_number, status, dateadd(day, -rn, daydate)
order by daydate
)
else 0
end daysPastDue
from (
select
t.*,
row_number() over(partition by loan_number, status order by daydate) rn
from mytable t
) t
order by loan_number, daydate
loan_number | daydate | status | daysPastDue
----------: | :--------- | :------- | ----------:
111111 | 2020-01-01 | Live | 0
111111 | 2020-01-02 | Live | 0
111111 | 2020-01-03 | PastDue | 1
111111 | 2020-01-04 | PastDue | 2
111111 | 2020-01-05 | Restruct | 0
111111 | 2020-01-06 | Restruct | 0
111111 | 2020-01-07 | Restruct | 0
111111 | 2020-01-08 | PastDue | 1
111111 | 2020-01-09 | PastDue | 2
111111 | 2020-01-10 | Closed | 0
这应该可以做到。
SELECT
t1.LoanNumber, t1.daydate, t1.Status, case
when status = 'Past Due'
then datediff(day,
(select max(daydate) from table1 t2
where t2.loanNumber =t1.loanNumber
and t2.daydate<t1.daydate and t2.status<> 'Past Due'
),
daydate)
else 0 end as [Days Past Due]
from table1 t1
你可以在sqlfiddle
上试试
我想从按日期排序的贷款列表中计算 DPD(逾期天数)。每个过去的到期日都应该重新计算。 参见附件中的示例。如何计算 "Days past due" 列?
出于某种原因,我将其视为 SQL 服务器。以下使用日期函数的 SQL 服务器约定。其他数据库也有类似的功能,但具体语法不同。
关键 ida -- 累积条件最大值 -- 没有改变:
select t.*,
(case when status = 'PastDue'
then datediff(date,
max(case when status <> 'PastDue' then dayDate end) over (partition by loadnumer order by daydate)
else 0
end) as daysPastDue
from t;
您想要计算 "past due" 的连续天数并在其间重置计数器。这是差距和孤岛问题。
如果日期总是增加 1 天,如示例数据所示,那么一种方法是取日期与 row_number()
之间的差异来定义每条记录所属的组。
你没有告诉你使用的是哪个数据库,所以这里有一个使用SQL服务器的dateadd()
进行日期计算的方法;不支持具有等效功能的数据库。
select
loan_number,
daydate,
status,
case when status = 'PastDue' then
count(*) over(
partition by loan_number, status, dateadd(day, -rn, daydate)
order by daydate
)
else 0
end daysPastDue
from (
select
t.*,
row_number() over(partition by loan_number, status order by daydate) rn
from mytable t
) t
order by loan_number, daydate
loan_number | daydate | status | daysPastDue ----------: | :--------- | :------- | ----------: 111111 | 2020-01-01 | Live | 0 111111 | 2020-01-02 | Live | 0 111111 | 2020-01-03 | PastDue | 1 111111 | 2020-01-04 | PastDue | 2 111111 | 2020-01-05 | Restruct | 0 111111 | 2020-01-06 | Restruct | 0 111111 | 2020-01-07 | Restruct | 0 111111 | 2020-01-08 | PastDue | 1 111111 | 2020-01-09 | PastDue | 2 111111 | 2020-01-10 | Closed | 0
这应该可以做到。
SELECT
t1.LoanNumber, t1.daydate, t1.Status, case
when status = 'Past Due'
then datediff(day,
(select max(daydate) from table1 t2
where t2.loanNumber =t1.loanNumber
and t2.daydate<t1.daydate and t2.status<> 'Past Due'
),
daydate)
else 0 end as [Days Past Due]
from table1 t1
你可以在sqlfiddle
上试试