2011-08-28 73 views
2

我想将日期范围拆分为相应的月份。
例如 - 我这有下列方式数据的视图:将日期范围拆分为几个月

user project startdate enddate 
----------------------------------- 
A abc1 2011-01-01 2011-12-31 
A abc2 2011-01-01 2011-05-01 
B xyz1 2011-01-01 2011-03-01 

我希望能够显示这样上面的数据:

user project startdate enddate  
A abc1 2011-01-01 2011-01-31 
A abc1 2011-02-01 2011-02-28 
A abc1 2011-03-01 2011-03-31 
---------------------------------- 
A abc2 2011-01-01 2011-01-31 
A abc2 2011-02-01 2011-02-28 
---------------------------------- 
B xyz1 2011-01-01 2011-01-31 
B xyz1 2011-02-01 2011-02-28 
B xyz1 2011-03-01 2011-03-31 

有人可以帮助我有了这个?

+1

你有什么试过?你知道SQL中没有行分隔符,对吗? –

回答

4

以下查询应该做的伎俩。 CTEWITH子句)动态生成我们可以用来加入的一些月份数据。

declare @test table (
    userid char(1), 
    project char(4), 
    startdate datetime, 
    enddate datetime) 

insert into @test 
select 'A', 'abc1', '1/1/2011', '12/31/2011' 
union select 'A', 'abc2', '1/1/2011', '5/1/2011' 
union select 'B', 'xyz1', '1/1/2011', '3/1/2011' 

--select * from @test 

;with MonthList as (
    select 
     DATEADD(month, M, '12/1/1899') as 'FirstDay', 
     dateadd(day, -1, dateadd(month, M + 1, '12/1/1899')) as 'LastDay', 
     DATEADD(month, M + 1, '12/1/1899') as 'FirstDayNextMonth' 
    from (
     select top 3000 ROW_NUMBER() over (order by s.name) as 'M' 
     from master..spt_values s) s 
) 

select 
    t.userid, t.project, ml.FirstDay, ml.LastDay 
from 
    @test t 
    inner join MonthList ml 
     on t.startdate < ml.FirstDayNextMonth 
      and t.enddate >= ml.FirstDay 
+0

优秀!!!这解决了我的问题。 – BoCode

+0

谢谢!它帮助我解决了一个问题。 – jherranzm

+0

如果我有时间与我的约会? 我试过上面的查询时,我有时间与日期定义,但分裂成几个月工作错误 –

0

这是一个给你你想要的程序。但是,如果你花时间学习CTE,这是一个更强大的方法(2005年及以后)。

create procedure dbo.ExpandProjects 
as 
begin 
    DECLARE @UserN CHAR(1) 
    DECLARE @Proj CHAR(4) 
    DECLARE @Start DATETIME 
    DECLARE @End DATETIME 
    DECLARE @DtLoop DATETIME 
    DECLARE @dtNExt DATETIME 

    SET NOCOUNT ON 

    CREATE TABLE #ProjList 
    (
     userName char(1), 
     project char(4), 
     startDate dateTime, 
     EndDate DateTime 
    ) 


    DECLARE db_cursor CURSOR FOR 
    SELECT * 
    FROM Projects 

    OPEN db_cursor 
    FETCH NEXT FROM db_cursor INTO @UserN,@Proj,@Start,@end 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     SET @DtLoop = STR(MONTH(@Start))+'/01/'+STR(YEAR(@Start)) 
     WHILE @DtLoop <= @End 
     BEGIN 
      SET @dtNext = DATEADD(m,1,@dtLoop) 

      INSERT INTO #ProjList 
         VALUES(@UserN,@Proj,@DtLoop,DateAdd(d,-1,@dtNExt)) 
      SET @DtLoop = @dtNext 


     END 

     PRINT @DtLoop 

     FETCH NEXT FROM db_cursor INTO @UserN,@Proj,@Start,@end 
    END 

    CLOSE db_cursor 
    DEALLOCATE db_cursor 

    SELECT * FROM #ProjList ORDER BY 1,2 



end