Sometimes data spans hours. This code takes something that begins in hour 1 and may not end till hour 2 or 3. It splits it into it's hourly components.
- HN is hour number
create function [dbo].[ufn_splithours]( @start datetime, @duration int ) returns @res table ( hn int, starttime datetime, endtime datetime ) as begin declare @actualend datetime set @actualend=dateadd(second,@duration, @start) declare @sdx datetime set @sdx=dbo.DateOnly(@start) declare @hnx int declare @tx table (hn int, starttime datetime, endtime datetime) SET @HNx=0 WHILE @HNx < 24 BEGIN INSERT INTO @Tx SELECT @HNx, @SDx, Dateadd(hh,1,@sdx) SET @SDx=DATEADD(HH,1,@SDx) SET @HNx=@HNx+1 END declare @endtime datetime declare @hourend datetime declare @hourstart datetime declare @dtx datetime set @dtx =@start declare @rowsx int set @rowsx=0 while @dtx < @actualend begin if @rowsx =0 begin -- first entry set @hnx=datepart(hour,@dtx) select @hourstart=starttime, @hourend=endtime from @tx where hn=@hnx insert into @res select @hnx, @start, @hourend set @rowsx=@rowsx+1 end set @dtx=dateadd(second,1,@dtx) if datepart(hh, @dtx ) > @hnx begin set @hnx=datepart(hour,@dtx) select @hourstart=starttime, @hourend=endtime from @tx where hn=@hnx if @actualend < @hourend set @hourend=@actualend insert into @res select @hnx, @hourstart, @hourend set @rowsx=@rowsx + 1 end end DELETE FROM @res WHERE STARTTIME=ENDTIME return end create function [dbo].[DateOnly](@DateTime DateTime) -- Returns @DateTime at midnight; i.e., it removes the time portion of a DateTime value. returns datetime as begin return dateadd(dd,0, datediff(dd,0,@DateTime)) end