sql—计算各日期的累计和,但不包括以后删除的数据

z4iuyo4d  于 2021-07-29  发布在  Java
关注(0)|答案(3)|浏览(277)

让我看看能不能解释清楚。
我有类似定期存款的数据

Placement Date | Maturity Date | Amount
2020-01-30     | 2020-03-30    | 50000
2020-02-05     | 2020-05-28    | 20000
2020-03-31     | 2020-05-30    | 7000
2020-04-13     | 2020-07-30    | 60000

我所期望的产出将是每月获得的累计金额,但不包括那些已经到期。

Month      | Amount
2020-01-31 | 50000
2020-02-29 | 70000
2020-03-31 | 27000 (due to the 50000 maturing on 03-30)
2020-04-30 | 87000
2020-05-31 | 60000 (due to the 20000 and 7000 maturing on 05-28 and 05-30)

到目前为止,我已经使用over子句来获得累计金额,但我不知道如何删除那些已经在接下来的几个月到期。
提前谢谢

332nm8kg

332nm8kg1#

最简单的解决方案是使用日历表(您可以很容易地找到如何在线构建一个日历表的示例,它可以用于其他报告目的)。
然后你可以这样做。

SELECT d.theDate, SUM(dp.Amount)
FROM dbo.AllDates d
JOIN dbo.Deposits dp
    ON d.theDate BETWEEN dp.placementDate AND dp.MaturityDate
WHERE d.LastDayOfTheMonth = 1
GROUP BY d.theDate
xzabzqsa

xzabzqsa2#

我正在考虑使用递归cte来生成日期,然后在原始表上进行连接和聚合:

with cte as (
    select 
        datefromparts(year(min(placement_date)), month(min(placement_date)), 1) dt,
        max(maturity_date) max_dt
    from mytable
    union all
    select 
        dateadd(month, 1, dt),
        max_dt
    from cte 
    where dateadd(month, 1, dt) < max_dt
)
select eomonth(c.dt) month, coalesce(sum(t.amount), 0) amount
from cte c
left join mytable t
    on eomonth(c.dt) between t.placement_date and t.maturity_date
group by c.dt
order by c.dt

db小提琴演示:

month      | amount
:--------- | -----:
2020-01-31 |  50000
2020-02-29 |  70000
2020-03-31 |  27000
2020-04-30 |  87000
2020-05-31 |  60000
2020-06-30 |  60000
2020-07-31 |      0
dffbzjpn

dffbzjpn3#

您可以直接在每一行上使用递归cte。也就是说,展开每一行以确定月末的值。然后聚合:

with cte as (
      select eomonth(placement_date) as eom, maturity_date, amount
      from t
      where eomonth(placement_date) < maturity_date
      union all
      select eomonth(dateadd(month, 1, eom)), maturity_date,
             (case when eomonth(dateadd(month, 1, eom)) < maturity_date then amount else 0 end)
      from cte 
      where eomonth(dateadd(month, 1, eom)) <= eomonth(maturity_date)
     )
select eom, sum(amount)
from cte
group by eom
order by eom;

这个查询有两个微妙之处:
比月末晚一个月的,不得为上月的最后一天。所以,2020-02-29+1个月是2020-03-29,而不是2020-03-31。因此使用 eomonth() 在递归部分。
您希望到期日的最后一个月在结果集中。因此 <= 在递归部分。
这是一把小提琴。

相关问题