尝试使用 CTE 生成两列之间的日期范围(每月生成 1 行)

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

我正在尝试将日期范围从单行分解为多行,下面是我希望看到的方式:

假设我有以下数据:

姓名 会员ID EFF_DATE TERM_DATE
约翰 1234 2020/01/01 2020/03/30

我很想看到:

姓名 会员ID 年麻木 月麻木 全体成员
约翰 1234 2020 1 2020/01/01
约翰 1234 2020 2 2020/02/01
约翰 1234 2020 3 2020/03/01

我当前的简化查询是:

 SELECT 
  Name
  ,[MemberID]
  ,[EFF_DATE]
  ,[TERM_DATE]
  FROM MYTABLE t


  where pat_id = '12121212' and rn = 1

我发现这个代码示例完全按照我想要的方式工作,但使用我当前的表/查询,但我不确定如何合并这两者。

DECLARE @DateStart DATE = '2021-01-20' , @DateEnd DATE = '2021-01-29';
with Extract_Dates_CTE (MyDate) as (
select @DateStart
Union ALL
select DATEADD(day, 1, MyDate)
from Extract_Dates_CTE
where MyDate < @DateEnd
)
select ROW_NUMBER() OVER(ORDER BY a.MyDate) AS RowDateID, a.MyDate AS ExtractedDates
from Extract_Dates_CTE a;

我不想使用数据变量,而是想使用简化查询中的表中包含的 EFF_DATE 和 TERM_DATE 列。非常感谢任何对此的帮助。

sql-server
1个回答
0
投票

这里不需要递归通用表表达式,您只需

JOIN
到您的日历表即可。 (你确实有一个,对吗?如果没有,为什么不呢?!去制作一个!)然后,解决方案实际上是一个简单的
JOIN
,确保日历日期位于有效/学期日期和日历日之间是第一天。我不知道你的日历表的定义是什么,但你的语句可能看起来像这样:

SELECT V.Name,
       V.MemberID,
       C.CalendarYear,
       C.CalendarMonth,
       C.CalendarDate
FROM (VALUES(N'John',1234,CONVERT(date,'20200101'),CONVERT(date,'20200330')))V(Name,MemberID,EFF_DATE,TERM_DATE) --Obviously this would actually be your table, not a construct
     JOIN tbl.Calendar C ON C.CalendarDate >= V.EFF_DATE
                        AND C.CalendarDate <= V.TERM_DATE
                        AND C.CalendarDay = 1;
© www.soinside.com 2019 - 2024. All rights reserved.