Sql 将日期范围从一行拆分为多行显示的月份
我有一个包含几百万个条目的表,所以我需要一个能够处理一系列不同场景的解决方案,因为我发现的大多数解决方案最多只能用于几个迭代 我有一个从开始到结束的状态检查,也就是帐户在这种状态下的时间。分割两个月的差额是没有问题的,但有相当多的条目是针对提前付款的账户的,因此它们的状态在2年内不会改变 原始简化表格如下所示:Sql 将日期范围从一行拆分为多行显示的月份,sql,sql-server,date,iteration,Sql,Sql Server,Date,Iteration,我有一个包含几百万个条目的表,所以我需要一个能够处理一系列不同场景的解决方案,因为我发现的大多数解决方案最多只能用于几个迭代 我有一个从开始到结束的状态检查,也就是帐户在这种状态下的时间。分割两个月的差额是没有问题的,但有相当多的条目是针对提前付款的账户的,因此它们的状态在2年内不会改变 原始简化表格如下所示: ID PERIOD_FROM PERIOD_TO DAYS ----------------------------------------------------
ID PERIOD_FROM PERIOD_TO DAYS
---------------------------------------------------------
115052454 02/04/2019 01/04/2021 730
115678935 06/04/2021 05/04/2023 729
119040627 06/04/2021 05/04/2023 729
115005487 01/04/2019 29/03/2021 728
116414279 17/04/2019 09/04/2021 723
116411046 17/04/2019 04/04/2021 718
116693271 24/04/2019 04/04/2021 711
123935704 05/07/2019 29/05/2021 694
119040627 16/05/2019 05/04/2021 690
115976183 02/05/2019 01/03/2021 669
ID PERIOD_FROM PERIOD_TO DAYS
------------------------------------------------------
1150524545 02/04/2019 30/04/2019 730
1150524545 01/05/2019 31/05/2019 730
1150524545 01/06/2019 30/06/2019 730
1150524545 01/07/2019 31/07/2019 730
………… ………… ………… ……
1150524545 01/02/2021 28/02/2021 730
1150524545 01/03/2021 31/03/2021 730
1150524545 01/04/2021 01/04/2021 730
我为两个月差异解决方案所做的是创建一个concat,如下所示:
CASE WHEN CONCAT(DATEPART(YYYY, [PERIOD_FROM]), FORMAT([PERIOD_FROM], 'MM')) = CONCAT(DATEPART(YYYY, [PERIOD_TO]), FORMAT([PERIOD_TO], 'MM'))
THEN CONCAT(DATEPART(YYYY, [PERIOD_FROM]), FORMAT([PERIOD_FROM], 'MM'))
ELSE CONCAT(DATEPART(YYYY, [PERIOD_FROM]), FORMAT([PERIOD_FROM], 'MM'), ',', DATEPART(YYYY, [PERIOD_TO]), FORMAT([PERIOD_TO], 'MM'))
END AS Period_Of
使用带字符串_split的交叉应用,我可以将行拆分为两行,使用另一个case语句,我可以根据从/到的周期是否等于或大于拆分值来分配完整值,但这只适用于两个月的差异,我最多需要48个月
我需要这样的输出:
ID PERIOD_FROM PERIOD_TO DAYS
---------------------------------------------------------
115052454 02/04/2019 01/04/2021 730
115678935 06/04/2021 05/04/2023 729
119040627 06/04/2021 05/04/2023 729
115005487 01/04/2019 29/03/2021 728
116414279 17/04/2019 09/04/2021 723
116411046 17/04/2019 04/04/2021 718
116693271 24/04/2019 04/04/2021 711
123935704 05/07/2019 29/05/2021 694
119040627 16/05/2019 05/04/2021 690
115976183 02/05/2019 01/03/2021 669
ID PERIOD_FROM PERIOD_TO DAYS
------------------------------------------------------
1150524545 02/04/2019 30/04/2019 730
1150524545 01/05/2019 31/05/2019 730
1150524545 01/06/2019 30/06/2019 730
1150524545 01/07/2019 31/07/2019 730
………… ………… ………… ……
1150524545 01/02/2021 28/02/2021 730
1150524545 01/03/2021 31/03/2021 730
1150524545 01/04/2021 01/04/2021 730
任何帮助都将不胜感激
更新:
多亏了Serg的帮助,我有了一个解决方案。我稍微调整了一下,使周期在最后一天结束,但在我的请求中没有指定,因为这不是主要问题。使用数字表
-- Generate table of 1000 numbers starting 0
with t0(n) as (
select n
from (
values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)
) t(n)
),nmbs as(
select row_number() over(order by t1.n) - 1 n
from t0 t1, t0 t2, t0 t3
)
--
select Id
, dateadd(mm, nmbs.n, tbl.PERIOD_FROM) PERIOD_FROM
, case when ys.NextDate > tbl.PERIOD_TO then tbl.PERIOD_TO else ys.NextDate end PERIOD_TO
, DAYS
, tbl.PERIOD_TO originalPERIOD_TO
from [my table] tbl
join nmbs
on dateadd(mm, nmbs.n, tbl.PERIOD_FROM) <= tbl.PERIOD_TO
cross apply (select dateadd(mm, nmbs.n + 1, tbl.PERIOD_FROM) NextDate) ys
order by ID, dateadd(mm, nmbs.n, tbl.PERIOD_FROM);
标记您的数据库管理系统。日期算法是特定于sql产品的。可能重复我正在sql Server 2017上工作,我尝试实现了您建议的链接,但没有解决我的问题,只是将我的行一分为二,其中应该有48行,并试图在我的月经结束后给我一个日期,这对我没有帮助。你可能想熟悉这个网站的工作方式。编辑你的标题并没有用,如有需要,,