sql >> Base de Datos >  >> RDS >> Sqlserver

dividir rango de fechas en meses

La siguiente consulta debería hacer el truco. El CTE (el WITH cláusula) genera dinámicamente algunos datos del mes que podemos usar para unirnos.

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