SQL 中的过期演变
Overdue evolution in SQL
尽管我努力了,但我还是想不出一种方法来满足我的需求:
我有 2 个 table 分别包含一组要偿还的贷款和一组这些贷款的偿还(并非所有贷款都有偿还条目 table 因为其中一些仍未支付)。
Table 贷款 有列:
- id
- 数量
- due_date
Table 报销 有列:
- id
- debt_id
- payment_date
我的目标是获取过去每个日期逾期5天以上的金额。
这是我所在的位置(在 Postgres 语法中):
with due_for_5_days_by_date AS (
select
due_date + interval '5' DAY as due_date,
sum(amount) as amount
FROM loan
GROUP BY due_date
),
paid_by_date as (
select
payment_date,
sum(amount) as amount
FROM reimbursement
join loan on loan.id = loan_id
GROUP BY payment_date
),
cumulated as (
SELECT
COALESCE(due_date, payment_date) as date,
SUM(COALESCE(paid_by_date.amount, 0)) over (order by COALESCE(due_date, payment_date)) as paid,
SUM(COALESCE(due_for_5_days_by_date.amount, 0)) over (order by COALESCE(due_date, payment_date)) as due_5d
FROM due_for_5_days_by_date
FULL OUTER JOIN paid_by_date on due_date = payment_date
)
select
DATE,
due_5d - paid as overdue_5d
from cumulated
order by date
解释:
- 首先,我得到每个日期恰好 5 天的应付金额
- 然后,我得到每个日期支付的金额
- 然后我将在 1. 和 2. 获得的金额相加,得到累计到期和已付金额
- 然后差分我得到逾期金额
但问题是,这样做的话,按日期支付的金额还包含偿还不到 5 天的贷款。换句话说,最终查询中每个日期的支付金额都被高估了,因为它应该不包括该日期最近到期的贷款收到的金额。我想不出解决这个问题的方法。
你能想办法得到我想要的吗?
非常感谢您的帮助!
我刚刚找到了这种方法,但它使用交叉连接,所以不确定它能否很好地扩展我的整个数据,即使它托管在 BigQuery 上:
with all_dates as (
select distinct payment_date as date
from reimbursement
union
select distinct due_date as date
from loan
union
select distinct due_date + interval '5' day as date
from loan
),
joined_data as (
SELECT
amount,
due_date,
payment_date
from loan
LEFT join reimbursement on loan.id = loan_id
)
select
date,
SUM(
CASE
WHEN (due_date <= DATE - INTERVAL '5' day) and (payment_date > DATE or payment_date is null) then amount
else 0
END
) as overdue_5d
FROM all_dates
cross join joined_data
group by date
order by DATE
尽管我努力了,但我还是想不出一种方法来满足我的需求:
我有 2 个 table 分别包含一组要偿还的贷款和一组这些贷款的偿还(并非所有贷款都有偿还条目 table 因为其中一些仍未支付)。
Table 贷款 有列:
- id
- 数量
- due_date
Table 报销 有列:
- id
- debt_id
- payment_date
我的目标是获取过去每个日期逾期5天以上的金额。
这是我所在的位置(在 Postgres 语法中):
with due_for_5_days_by_date AS (
select
due_date + interval '5' DAY as due_date,
sum(amount) as amount
FROM loan
GROUP BY due_date
),
paid_by_date as (
select
payment_date,
sum(amount) as amount
FROM reimbursement
join loan on loan.id = loan_id
GROUP BY payment_date
),
cumulated as (
SELECT
COALESCE(due_date, payment_date) as date,
SUM(COALESCE(paid_by_date.amount, 0)) over (order by COALESCE(due_date, payment_date)) as paid,
SUM(COALESCE(due_for_5_days_by_date.amount, 0)) over (order by COALESCE(due_date, payment_date)) as due_5d
FROM due_for_5_days_by_date
FULL OUTER JOIN paid_by_date on due_date = payment_date
)
select
DATE,
due_5d - paid as overdue_5d
from cumulated
order by date
解释:
- 首先,我得到每个日期恰好 5 天的应付金额
- 然后,我得到每个日期支付的金额
- 然后我将在 1. 和 2. 获得的金额相加,得到累计到期和已付金额
- 然后差分我得到逾期金额
但问题是,这样做的话,按日期支付的金额还包含偿还不到 5 天的贷款。换句话说,最终查询中每个日期的支付金额都被高估了,因为它应该不包括该日期最近到期的贷款收到的金额。我想不出解决这个问题的方法。
你能想办法得到我想要的吗?
非常感谢您的帮助!
我刚刚找到了这种方法,但它使用交叉连接,所以不确定它能否很好地扩展我的整个数据,即使它托管在 BigQuery 上:
with all_dates as (
select distinct payment_date as date
from reimbursement
union
select distinct due_date as date
from loan
union
select distinct due_date + interval '5' day as date
from loan
),
joined_data as (
SELECT
amount,
due_date,
payment_date
from loan
LEFT join reimbursement on loan.id = loan_id
)
select
date,
SUM(
CASE
WHEN (due_date <= DATE - INTERVAL '5' day) and (payment_date > DATE or payment_date is null) then amount
else 0
END
) as overdue_5d
FROM all_dates
cross join joined_data
group by date
order by DATE