这是我的实际数据
身份证 | 开始日期时间 | 结束日期时间 | 价格 |
---|---|---|---|
1 | 2024-01-01 | 2024-06-30 | 14.00 |
2 | 2024-07-01 | 2024-12-30 | 10.00 |
预期产量
身份证 | 开始日期时间 | 结束日期时间 | 价格 |
---|---|---|---|
1 | 2024-01-01 | 2024-03-31 | 14.00 |
1 | 2024-04-01 | 2024-06-30 | 14.00 |
2 | 2024-07-01 | 2024-09-30 | 10.00 |
2 | 2024-10-01 | 2024-12-30 | 10.00 |
尝试过这个,但这将从第二季度开始
with cte as (
select id, start_date, num_quarters
from t
union all
select id, dateadd(month, 3, start_date), num_quarters - 1
from cte
where num_quarters > 1
)
select *
from cte;
在 SQL Server 2022 上,您可以使用
DATETRUNC()
、DATEDIFF()
、GENERATE_SERIES()
和 DATEADD()
的组合来生成四分之一。然后可以应用函数 LEAST()
和 GREATEST()
将第一季度和最后一个季度修剪到原始范围(例如在 '2024-12-30'
结束日期情况下。不需要 CTE。
逻辑:
DATEDIFF()
计算所需的季度数 - 1。GENERATE_SERIES()
生成数字范围 1..N.DATETRUNC()
用于计算计算季度开始和结束日期的基准日期。DATEADD()
然后计算这些日期。季度结束日期是通过添加额外的季度并减去一天来计算的。LEAST()
和 GREATEST()
将第一个和最后四分之一修剪到原始范围。SELECT T.ID, D.StartDateTime, D.EndDateTime, T.Price
FROM Data T
CROSS APPLY GENERATE_SERIES(0, DATEDIFF(quarter, T.StartDateTime, T.EndDateTime)) S
CROSS APPLY (SELECT DATETRUNC(quarter, T.StartDateTime) AS QStart) Q
CROSS APPLY (
SELECT
GREATEST(
DATEADD(quarter, S.value, Q.QStart),
T.StartDateTime
) AS StartDateTime,
LEAST(
DATEADD(day, -1, DATEADD(quarter, S.value + 1, Q.QStart)),
T.EndDateTime
) AS EndDateTime
) D
ORDER BY T.ID, D.StartDateTime
结果(带有一些额外的测试数据):
身份证 | 开始日期时间 | 结束日期时间 | 价格 |
---|---|---|---|
1 | 2024-01-01 | 2024-03-31 | 14.00 |
1 | 2024-04-01 | 2024-06-30 | 14.00 |
2 | 2024-07-01 | 2024-09-30 | 10.00 |
2 | 2024-10-01 | 2024-12-30 | 10.00 |
3 | 2023-11-15 | 2023-12-31 | 88.00 |
3 | 2024-01-01 | 2024-03-31 | 88.00 |
3 | 2024-04-01 | 2024-06-30 | 88.00 |
3 | 2024-07-01 | 2024-08-14 | 88.00 |
4 | 2024-07-15 | 2024-08-14 | 99.00 |
参见这个数据库<>小提琴。