如何查找提供的日期范围内的所有季度开始和结束日期

问题描述 投票:0回答:1

这是我的实际数据

身份证 开始日期时间 结束日期时间 价格
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 sql-server
1个回答
0
投票

在 SQL Server 2022 上,您可以使用

DATETRUNC()
DATEDIFF()
GENERATE_SERIES()
DATEADD()
的组合来生成四分之一。然后可以应用函数
LEAST()
GREATEST()
将第一季度和最后一个季度修剪到原始范围(例如在
'2024-12-30'
结束日期情况下。不需要 CTE。

逻辑:

  1. DATEDIFF()
    计算所需的季度数 - 1。
  2. GENERATE_SERIES()
    生成数字范围 1..N.
  3. DATETRUNC()
    用于计算计算季度开始和结束日期的基准日期。
  4. DATEADD()
    然后计算这些日期。季度结束日期是通过添加额外的季度并减去一天来计算的。
  5. 然后可以应用
    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

参见这个数据库<>小提琴

© www.soinside.com 2019 - 2024. All rights reserved.