由于对用例的误解而改变了问题。
Amazon Redshift查询以下问题声明。
数据结构:
表格:
id acc_id status s_id due_date principal
9999957 10003 PAID 102 2018-07-02 12:00:00 4205
9999958 10003 UNPAID 103 2018-08-02 12:00:00 4100
9999959 10003 UNPAID 104 2018-09-02 12:00:00 4266
9999960 10003 UNPAID 105 2018-10-02 12:00:00 4286
9999962 10004 PAID 106 2018-07-02 12:00:00 3200
9999963 10004 PAID 107 2018-08-02 12:00:00 3100
9999964 10004 UNPAID 108 2018-09-02 12:00:00 3266
9999965 10004 UNPAID 109 2018-10-02 12:00:00 3286
用例-
未付款项在到期日之后变为拖欠(过期)。
因此,我需要计算从本月的第一个到期日到7月2日到最后一个到期日(假设是当月的11月2日)在每个月底的拖欠金额 < / p>
我还需要计算该月底到期的天数。
来自以上数据的插图:
收获:我需要为贷款(acc_id)而不是emi进行计算。
进一步说明,第一个EMI将在第一个月到期29天,第二个月将到期59天,第二EMI也将在第二个月到期29天。 但是我需要在贷款级别(acc_id)。
同一示例继续到9月30日,acc_id 10003自8月2日起到期,因此从9月30日起,到期金额为8366(4100 + 4266),DPD(days_past_due)为59(29 + 30)。
acc_id 10004也应为3100,DPD为28(9月30日至9月2日)。
最终输出将是这样的:
Month_End DPD_Band Amount
2018/08/31 0-29 4100
2018/08/31 30-59 0
2018/08/31 60-89 0
2018/08/31 90+ 0
2018/09/30 0-29 3100
2018/09/30 30-59 8366
2018/09/30 60-89 0
2018/09/30 90+ 0
查询尝试:DPD波段可以根据拖欠日期的个案陈述来创建。我需要真正的帮助,首先要创建月末,然后按上述在不同的拖欠天数中找到投资组合级别的金额。
答案 0 :(得分:0)
在操作说明了哪个RDBMS之后,编辑为与RedShift兼容。 (MySQL需要一个不同的答案)
以下内容为您的第一条记录到上个月末之间的每个月创建一个记录。
然后将其加入您的未付款记录中,然后聚合选择将结果放入哪个括号。
WITH
first_month AS
(
SELECT LAST_DAY(MIN(due_date)) AS end_date FROM yourTable
),
months AS
(
SELECT
LAST_DAY(ADD_MONTHS(first_month.end_date, s.id)) AS end_date
FROM
first_month
CROSS JOIN
generate_series(
1,
DATEDIFF(month, (SELECT end_date FROM first_month), CURRENT_DATE)
)
AS s(id)
),
monthly_delinquents AS
(
SELECT
yourTable.*,
months.end_date AS month_end_date,
DATEDIFF(DAY, yourTable.due_date, months.end_date) AS days_past_due
FROM
months
LEFT JOIN
yourTable
ON yourTable.status = 'UNPAID'
AND yourTable.due_date < months.end_date
)
SELECT
month_end_date,
SUM(CASE WHEN days_past_due >= 00 AND days_past_due < 30 THEN principal ELSE 0 END) AS dpd_00_29,
SUM(CASE WHEN days_past_due >= 30 AND days_past_due < 60 THEN principal ELSE 0 END) AS dpd_30_59,
SUM(CASE WHEN days_past_due >= 60 AND days_past_due < 90 THEN principal ELSE 0 END) AS dpd_60_89,
SUM(CASE WHEN days_past_due >= 90 THEN principal ELSE 0 END) AS dpd_90plus
FROM
monthly_delinquents
GROUP BY
month_end_date
ORDER BY
month_end_date
也就是说,通常将这样的事情变为现实的想法不是一个好主意。当一年到期的时候会发生什么?它只属于90plus类别,永远不会移动。而且,如果要扩展它,则需要更改查询以及您曾经编写的任何依赖此查询的查询。
相反,您可以标准化输出...
WITH
first_month AS
(
SELECT LAST_DAY(MIN(due_date)) AS end_date FROM yourTable
),
months AS
(
SELECT
LAST_DAY(ADD_MONTHS(first_month.end_date, s.id)) AS end_date
FROM
first_month
CROSS JOIN
generate_series(
1,
DATEDIFF(month, (SELECT end_date FROM first_month), CURRENT_DATE)
)
AS s(id)
),
monthly_delinquents AS
(
SELECT
yourTable.*,
months.end_date AS month_end_date,
DATEDIFF(DAY, yourTable.due_date, months.end_date) AS days_past_due
FROM
months
LEFT JOIN
yourTable
ON yourTable.status = 'UNPAID'
AND yourTable.due_date < months.end_date
)
SELECT
month_end_date,
(days_past_due / 30) * 30 AS days_past_due_band,
SUM(principal) AS total_principal,
COUNT(*) AS total_rows
FROM
monthly_delinquents
GROUP BY
month_end_date,
(days_past_due / 30) * 30
ORDER BY
month_end_date,
(days_past_due / 30) * 30