创建滚动周期
Creating Rolling Periods
我想每 6 个月创建一个滚动周期,但我不确定执行此操作的最佳方法。我猜这可能必须递归完成?
我有一笔付款 table,其中包含类似于以下内容的数据:
CREATE TABLE payments
([id] int, [payment_month] int, [payment_date] datetime, [payment_amount] int)
;
INSERT INTO payments
([id], [payment_month], [payment_date], [payment_amount])
VALUES
(1, 201911, '2019-11-01 00:00:00', 50),
(1, 201912, '2019-12-01 00:00:00', 50),
(1, 202001, '2020-01-01 00:00:00', 50),
(1, 202002, '2020-02-01 00:00:00', 50),
(1, 202003, '2020-03-01 00:00:00', 50),
(1, 202004, '2020-04-01 00:00:00', 50),
(1, 202005, '2020-05-01 00:00:00', 50),
(1, 202006, '2020-06-01 00:00:00', 25),
(1, 202007, '2020-07-01 00:00:00', 50),
(1, 202008, '2020-08-01 00:00:00', 50),
(1, 202009, '2020-09-01 00:00:00', 15),
(2, 201911, '2019-11-01 00:00:00', 50),
(2, 201912, '2019-12-01 00:00:00', 50),
(2, 202001, '2020-01-01 00:00:00', 25),
(2, 202002, '2020-02-01 00:00:00', 50),
(2, 202003, '2020-03-01 00:00:00', 45),
(2, 202004, '2020-04-01 00:00:00', 45),
(2, 202004, '2020-04-10 00:00:00', 20),
(2, 202005, '2020-05-01 00:00:00', 25),
(3, 202004, '2020-04-01 00:00:00', 50),
(3, 202005, '2020-05-01 00:00:00', 50),
(3, 202006, '2020-06-01 00:00:00', 50),
(3, 202007, '2020-07-01 00:00:00', 50),
(3, 202008, '2020-08-01 00:00:00', 50),
(3, 202009, '2020-09-01 00:00:00', 300)
;
我还有一个日历 table,我正在使用 returns 数据,如下所示:
CREATE TABLE calendar
([CalendarPeriod] int, [CalendarDate] datetime)
;
INSERT INTO calendar
([CalendarPeriod], [CalendarDate])
VALUES
(202004, '2020-04-30 00:00:00'),
(202005, '2020-05-31 00:00:00'),
(202006, '2020-06-30 00:00:00'),
(202007, '2020-07-31 00:00:00'),
(202008, '2020-08-31 00:00:00'),
(202009, '2020-09-30 00:00:00')
;
我希望得到一个输出,其中 calendar
中的每个 CalendarPeriod
都与自身和前 5 个月配对。 CalendarPeriod
作为一个报告周期,每个月的滚动周期为6个月。我的最终目标是通过 payment_month
加入 payment_amounts
到每个报告期,其中 payment_month
等于报告期中的滚动月份之一。
编辑:
我对几个月和滚动周期的预期输出看起来像下面的 table。如果需要,我可以操纵 table 以按 CalendarPeriod
聚合。
+----------------+----------------+----------------+
| CalendarPeriod | rolling_period | rolling_amount |
+----------------+----------------+----------------+
| 202004 | 201911 | 100 |
+----------------+----------------+----------------+
| 202004 | 201912 | 100 |
+----------------+----------------+----------------+
| 202004 | 202001 | 75 |
+----------------+----------------+----------------+
| 202004 | 202002 | 100 |
+----------------+----------------+----------------+
| 202004 | 202003 | 95 |
+----------------+----------------+----------------+
| 202004 | 202004 | 165 |
+----------------+----------------+----------------+
| 202005 | 201912 | 100 |
+----------------+----------------+----------------+
| 202005 | 202001 | 75 |
+----------------+----------------+----------------+
| 202005 | 202002 | 100 |
+----------------+----------------+----------------+
| 202005 | 202003 | 95 |
+----------------+----------------+----------------+
| 202005 | 202004 | 165 |
+----------------+----------------+----------------+
| 202005 | 202005 | 125 |
+----------------+----------------+----------------+
| 202006 | 202001 | 75 |
+----------------+----------------+----------------+
| 202006 | 202002 | 100 |
+----------------+----------------+----------------+
| 202006 | 202003 | 95 |
+----------------+----------------+----------------+
| 202006 | 202004 | 165 |
+----------------+----------------+----------------+
| 202006 | 202005 | 125 |
+----------------+----------------+----------------+
| 202006 | 202006 | 75 |
+----------------+----------------+----------------+
| 202007 | 202002 | 100 |
+----------------+----------------+----------------+
| 202007 | 202003 | 95 |
+----------------+----------------+----------------+
| 202007 | 202004 | 165 |
+----------------+----------------+----------------+
| 202007 | 202005 | 125 |
+----------------+----------------+----------------+
| 202007 | 202006 | 75 |
+----------------+----------------+----------------+
| 202007 | 202007 | 100 |
+----------------+----------------+----------------+
| 202008 | 202003 | 95 |
+----------------+----------------+----------------+
| 202008 | 202004 | 165 |
+----------------+----------------+----------------+
| 202008 | 202005 | 125 |
+----------------+----------------+----------------+
| 202008 | 202006 | 75 |
+----------------+----------------+----------------+
| 202008 | 202007 | 100 |
+----------------+----------------+----------------+
| 202008 | 202008 | 100 |
+----------------+----------------+----------------+
| 202009 | 202004 | 165 |
+----------------+----------------+----------------+
| 202009 | 202005 | 125 |
+----------------+----------------+----------------+
| 202009 | 202006 | 75 |
+----------------+----------------+----------------+
| 202009 | 202007 | 100 |
+----------------+----------------+----------------+
| 202009 | 202008 | 100 |
+----------------+----------------+----------------+
| 202009 | 202009 | 315 |
+----------------+----------------+----------------+
-- Alternate:
+----------------+----------------+
| CalendarPeriod | rolling_amount |
+----------------+----------------+
| 202004 | 635 |
+----------------+----------------+
| 202005 | 660 |
+----------------+----------------+
| 202006 | 635 |
+----------------+----------------+
| 202007 | 660 |
+----------------+----------------+
| 202008 | 660 |
+----------------+----------------+
| 202009 | 880 |
+----------------+----------------+
在此先感谢您的帮助。
据我了解你的问题,你想要每个期间过去 6 个月的滚动付款总和。
我不认为您真的需要您展示的中间数据集来实现这个目标。您可以只使用 window 函数:
select c.calendarperiod,
sum(p.payment_amount) month_amount,
sum(sum(p.payment_amount)) over(
order by c.calendarperiod
rows between 5 preceding and current row
) rolling_6_month_amount
from calendar c
left join payments p
on p.payment_date >= datefromparts(year(c.calendardate), month(c.calendardate), 1)
and p.payment_date < dateadd(day, 1, c.calendardate)
group by c.calendarperiod
查询从日历开始,并为每个月带来相应的付款 - 我调整了日期间隔,以防在该月的最后一天有付款。然后,我们按期间汇总。最后,我们可以使用 window 函数回顾过去 5 个时期并对相应的付款求和。
我想每 6 个月创建一个滚动周期,但我不确定执行此操作的最佳方法。我猜这可能必须递归完成?
我有一笔付款 table,其中包含类似于以下内容的数据:
CREATE TABLE payments
([id] int, [payment_month] int, [payment_date] datetime, [payment_amount] int)
;
INSERT INTO payments
([id], [payment_month], [payment_date], [payment_amount])
VALUES
(1, 201911, '2019-11-01 00:00:00', 50),
(1, 201912, '2019-12-01 00:00:00', 50),
(1, 202001, '2020-01-01 00:00:00', 50),
(1, 202002, '2020-02-01 00:00:00', 50),
(1, 202003, '2020-03-01 00:00:00', 50),
(1, 202004, '2020-04-01 00:00:00', 50),
(1, 202005, '2020-05-01 00:00:00', 50),
(1, 202006, '2020-06-01 00:00:00', 25),
(1, 202007, '2020-07-01 00:00:00', 50),
(1, 202008, '2020-08-01 00:00:00', 50),
(1, 202009, '2020-09-01 00:00:00', 15),
(2, 201911, '2019-11-01 00:00:00', 50),
(2, 201912, '2019-12-01 00:00:00', 50),
(2, 202001, '2020-01-01 00:00:00', 25),
(2, 202002, '2020-02-01 00:00:00', 50),
(2, 202003, '2020-03-01 00:00:00', 45),
(2, 202004, '2020-04-01 00:00:00', 45),
(2, 202004, '2020-04-10 00:00:00', 20),
(2, 202005, '2020-05-01 00:00:00', 25),
(3, 202004, '2020-04-01 00:00:00', 50),
(3, 202005, '2020-05-01 00:00:00', 50),
(3, 202006, '2020-06-01 00:00:00', 50),
(3, 202007, '2020-07-01 00:00:00', 50),
(3, 202008, '2020-08-01 00:00:00', 50),
(3, 202009, '2020-09-01 00:00:00', 300)
;
我还有一个日历 table,我正在使用 returns 数据,如下所示:
CREATE TABLE calendar
([CalendarPeriod] int, [CalendarDate] datetime)
;
INSERT INTO calendar
([CalendarPeriod], [CalendarDate])
VALUES
(202004, '2020-04-30 00:00:00'),
(202005, '2020-05-31 00:00:00'),
(202006, '2020-06-30 00:00:00'),
(202007, '2020-07-31 00:00:00'),
(202008, '2020-08-31 00:00:00'),
(202009, '2020-09-30 00:00:00')
;
我希望得到一个输出,其中 calendar
中的每个 CalendarPeriod
都与自身和前 5 个月配对。 CalendarPeriod
作为一个报告周期,每个月的滚动周期为6个月。我的最终目标是通过 payment_month
加入 payment_amounts
到每个报告期,其中 payment_month
等于报告期中的滚动月份之一。
编辑:
我对几个月和滚动周期的预期输出看起来像下面的 table。如果需要,我可以操纵 table 以按 CalendarPeriod
聚合。
+----------------+----------------+----------------+
| CalendarPeriod | rolling_period | rolling_amount |
+----------------+----------------+----------------+
| 202004 | 201911 | 100 |
+----------------+----------------+----------------+
| 202004 | 201912 | 100 |
+----------------+----------------+----------------+
| 202004 | 202001 | 75 |
+----------------+----------------+----------------+
| 202004 | 202002 | 100 |
+----------------+----------------+----------------+
| 202004 | 202003 | 95 |
+----------------+----------------+----------------+
| 202004 | 202004 | 165 |
+----------------+----------------+----------------+
| 202005 | 201912 | 100 |
+----------------+----------------+----------------+
| 202005 | 202001 | 75 |
+----------------+----------------+----------------+
| 202005 | 202002 | 100 |
+----------------+----------------+----------------+
| 202005 | 202003 | 95 |
+----------------+----------------+----------------+
| 202005 | 202004 | 165 |
+----------------+----------------+----------------+
| 202005 | 202005 | 125 |
+----------------+----------------+----------------+
| 202006 | 202001 | 75 |
+----------------+----------------+----------------+
| 202006 | 202002 | 100 |
+----------------+----------------+----------------+
| 202006 | 202003 | 95 |
+----------------+----------------+----------------+
| 202006 | 202004 | 165 |
+----------------+----------------+----------------+
| 202006 | 202005 | 125 |
+----------------+----------------+----------------+
| 202006 | 202006 | 75 |
+----------------+----------------+----------------+
| 202007 | 202002 | 100 |
+----------------+----------------+----------------+
| 202007 | 202003 | 95 |
+----------------+----------------+----------------+
| 202007 | 202004 | 165 |
+----------------+----------------+----------------+
| 202007 | 202005 | 125 |
+----------------+----------------+----------------+
| 202007 | 202006 | 75 |
+----------------+----------------+----------------+
| 202007 | 202007 | 100 |
+----------------+----------------+----------------+
| 202008 | 202003 | 95 |
+----------------+----------------+----------------+
| 202008 | 202004 | 165 |
+----------------+----------------+----------------+
| 202008 | 202005 | 125 |
+----------------+----------------+----------------+
| 202008 | 202006 | 75 |
+----------------+----------------+----------------+
| 202008 | 202007 | 100 |
+----------------+----------------+----------------+
| 202008 | 202008 | 100 |
+----------------+----------------+----------------+
| 202009 | 202004 | 165 |
+----------------+----------------+----------------+
| 202009 | 202005 | 125 |
+----------------+----------------+----------------+
| 202009 | 202006 | 75 |
+----------------+----------------+----------------+
| 202009 | 202007 | 100 |
+----------------+----------------+----------------+
| 202009 | 202008 | 100 |
+----------------+----------------+----------------+
| 202009 | 202009 | 315 |
+----------------+----------------+----------------+
-- Alternate:
+----------------+----------------+
| CalendarPeriod | rolling_amount |
+----------------+----------------+
| 202004 | 635 |
+----------------+----------------+
| 202005 | 660 |
+----------------+----------------+
| 202006 | 635 |
+----------------+----------------+
| 202007 | 660 |
+----------------+----------------+
| 202008 | 660 |
+----------------+----------------+
| 202009 | 880 |
+----------------+----------------+
在此先感谢您的帮助。
据我了解你的问题,你想要每个期间过去 6 个月的滚动付款总和。
我不认为您真的需要您展示的中间数据集来实现这个目标。您可以只使用 window 函数:
select c.calendarperiod,
sum(p.payment_amount) month_amount,
sum(sum(p.payment_amount)) over(
order by c.calendarperiod
rows between 5 preceding and current row
) rolling_6_month_amount
from calendar c
left join payments p
on p.payment_date >= datefromparts(year(c.calendardate), month(c.calendardate), 1)
and p.payment_date < dateadd(day, 1, c.calendardate)
group by c.calendarperiod
查询从日历开始,并为每个月带来相应的付款 - 我调整了日期间隔,以防在该月的最后一天有付款。然后,我们按期间汇总。最后,我们可以使用 window 函数回顾过去 5 个时期并对相应的付款求和。