我有一个
的数据集Name|ID|Start_DATE|END_DATE
我想在活跃的几个月里休息一下。
示例:
Bob Smith|1001|2016-12-01|2017-02-18
将返回日期之间列出的所有月份
Bob Smith|1001|2016-12-01
Bob Smith|1001|2017-01-01
Bob Smith|1001|2017-02-02
根据我发现的日期,我一直在计划一些数据。一旦我弄清楚基本查询,我还需要处理列为9999-12-31
的活跃员工。
declare @startDate date;
declare @endDate date;
select @startDate = '20100101';
select @endDate = '20150531';
with dateRange as
(
select dt = dateadd(mm, 0, @startDate)
where dateadd(mm, 0, @startDate) < @endDate
union all
select dateadd(mm, 1, dt)
from dateRange
where dateadd(mm, 1, dt) < @endDate
)
select *
from dateRange
有没有更好的方法来处理它?</ p>
答案 0 :(得分:0)
假设我理解这个问题,这是一种方法:
首先,创建并填充样本表(请在将来的问题中将此步骤保存起来)
DECLARE @T AS TABLE
(
Name varchar(20),
ID int,
Start_DATE date,
END_DATE date
)
INSERT INTO @T VALUES
('Bob Smith', 1001, '2016-12-01', '2017-02-18')
您的问题中的DateRange日历cte,其中包含适合样本数据的日期:
declare @startDate date;
declare @endDate date;
select @startDate = '20150101';
select @endDate = '20200531';
with dateRange as
(
select dt = dateadd(mm, 0, @startDate)
where dateadd(mm, 0, @startDate) < @endDate
union all
select dateadd(mm, 1, dt)
from dateRange
where dateadd(mm, 1, dt) < @endDate
)
查询:
SELECT Name,
ID,
CONVERT(char(12), Start_DATE, 107) As StartDate, -- just to see it clearly in the results
CONVERT(char(12), END_DATE, 107) As EndDate, -- just to see it clearly in the results
CONVERT(char(12), dt, 107) As ActiveMonth
FROM @T
INNER JOIN dateRange ON dt >= Start_DATE AND dt < END_DATE
结果:
Name ID StartDate EndDate ActiveMonth
Bob Smith 1001 Dec 01, 2016 Feb 18, 2017 Dec 01, 2016
Bob Smith 1001 Dec 01, 2016 Feb 18, 2017 Jan 01, 2017
Bob Smith 1001 Dec 01, 2016 Feb 18, 2017 Feb 01, 2017
顺便说一句,有一种更好的方法来创建一个日历cte,使用数字(或计数)表。 here a demo.