假设我有一个数据集:
rowID | dateStart | dateEnd | Year | Month
121 | 2013-10-03 | 2013-12-03 | NULL | NULL
143 | 2013-12-11 | 2014-03-11 | NULL | NULL
322 | 2014-01-02 | 2014-02-11 | NULL | NULL
我希望sql根据dateStart和dateEnd生成以下数据源。请注意年份和月份分组。
rowID | dateStart | dateEnd | Year | Month
121 | 2013-10-03 | 2013-12-03 | 2013 | 10
121 | 2013-10-03 | 2013-12-03 | 2013 | 11
121 | 2013-10-03 | 2013-12-03 | 2013 | 12
143 | 2013-12-11 | 2014-03-11 | 2013 | 12
143 | 2013-12-11 | 2014-03-11 | 2014 | 1
143 | 2013-12-11 | 2014-03-11 | 2014 | 2
143 | 2013-12-11 | 2014-03-11 | 2014 | 3
322 | 2014-01-02 | 2014-02-11 | 2014 | 1
322 | 2014-01-02 | 2014-02-11 | 2014 | 2
我很难绕过这一个。有什么想法吗?
答案 0 :(得分:10)
通过创建整数列表然后使用它来递增日期,我发现最容易解决这些问题。这是一个例子:
with nums as (
select 0 as n
union all
select n + 1 as n
from nums
where n < 11
)
select rowid, datestart, dateend,
year(dateadd(month, n.n, datestart)) as yr,
month(dateadd(month, n.n, datestart)) as mon
from table t join
nums n
on dateadd(month, n.n - 1, datestart) <= dateend;
答案 1 :(得分:1)
首先,创建一个带有2个日期的表值函数,并将年和月作为表格返回:
create function dbo.YearMonths(@StartDate DateTime, @EndDate DateTime)
returns @YearMonths table
([Year] int,
[Month] int)
as
begin
set @EndDate = DATEADD(month, 1, @EndDate)
while (@StartDate < @EndDate)
begin
insert into @YearMonths
select YEAR(@StartDate), MONTH(@StartDate)
set @StartDate = DATEADD(month, 1, @StartDate)
end
return
end
以下为例:
select *
from dbo.YearMonths('1/1/2014', '5/1/2014')
返回:
然后你会像这样加入它以获得你想要的东西:
select m.*, ym.Year, ym.Month
from myTable m
cross apply dbo.YearMonths(dateStart, dateEnd) ym
答案 2 :(得分:0)
试试这个:
declare @months table(mth int)
insert into @months values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)
declare @calendar table(yr int,mth int)
insert into @calendar
select distinct year(datestart),mth
from tbl cross join @months
union
select distinct year(dateend),mth
from tbl cross join @months
select t.rowID, t.datestart, t.dateend, y.yr [Year], y.mth [Month]
from
yourtable t
inner join @calendar y on year(datestart) = yr or year(dateend) = yr
where
(mth >= month(datestart) and mth <= month(dateend) and year(datestart) = year(dateend))
or
(year(datestart) < year(dateend))
and
(year(datestart) = yr and mth >= month(datestart) --All months of start year
or
(year(dateend) = yr and mth <= month(dateend))) -- All months of end year
order by t.rowID, [Year],[Month]
我们创建了一个&#39;日历表&#39;其中列出了源表中存在的所有月份和年份组合。然后,我们根据年份将源表连接到日历表,并根据需要进行过滤。