This script creates a scalar function, F_END_OF_WEEK, that returns the end of week date for a passed date and a passed start day of week.Parameter @DATE can be any valid datetime. Parameter @WEEK_START_DAY must be an integer in the range 1 through 7, with Sun = 1, Mon = 2, Tue = 3, Wed = 4, Thu = 5, Fri = 6, and Sat = 7.This function is a companion to function F_START_OF_WEEK and has the same input parameters, @DATE and @WEEK_START_DAY. If they are called with the same input parameters, they will return the first and last day of the week. Function F_END_OF_WEEK will return a null if the end of week day would be later than 9999-12-31.The test code at the end of the script uses function F_START_OF_WEEK which can be found on this link:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=47307The test code at the end of the script uses function F_TABLE_NUMBER_RANGE which can be found on this link:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=47685There are other Start of Time Period Functions posted here:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=64755There are other End Date of Time Period Functions here:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=64759/*Function created by this script: dbo.F_END_OF_WEEK( @DATE, @WEEK_START_DAY )*/if objectproperty(object_id('dbo.F_END_OF_WEEK'),'IsScalarFunction') = 1 begin drop function dbo.F_END_OF_WEEK endgocreate function dbo.F_END_OF_WEEK( @DATE datetime, -- Sun = 1, Mon = 2, Tue = 3, Wed = 4 -- Thu = 5, Fri = 6, Sat = 7 -- Default to Sunday @WEEK_START_DAY int = 1 )/*Function: F_END_OF_WEEK Finds start of last day of week at 00:00:00.000 for input datetime, @DAY, for a week that started on the day of week of @WEEK_START_DAY. Returns a null if the end of week date would be after 9999-12-31.*/returns datetimeasbegindeclare @END_OF_WEEK_DATE datetimedeclare @FIRST_BOW datetimedeclare @LAST_EOW datetime-- Check for valid day of week, and return null if invalidif not @WEEK_START_DAY between 1 and 7 return null-- Find the last end of week for the passed day of weekselect @LAST_EOW =convert(datetime,2958457+((@WEEK_START_DAY+6)%7))-- Return null if end of week for date passed is after 9999-12-31if @DATE > @LAST_EOW return null-- Find the first valid beginning of week for the date passed.select @FIRST_BOW = convert(datetime,-53690+((@WEEK_START_DAY+5)%7))-- If date is before the first beginning of week for the passed day of week-- return the day before the first beginning of weekif @DATE < @FIRST_BOW begin set @END_OF_WEEK_DATE = dateadd(dd,-1,@FIRST_BOW) return @END_OF_WEEK_DATE end-- Find end of week for the normal case as 6 days after the beginning of weekselect @END_OF_WEEK_DATE = dateadd(dd,((datediff(dd,@FIRST_BOW,@DATE)/7)*7)+6,@FIRST_BOW)return @END_OF_WEEK_DATEendgo/*Start of test script*/select [DATE] = convert(varchar(10),a.DT,121), --WEEK_START_DAY = convert(varchar(2),b.number), FUNC_DW = case b.number when 1 then 'Sun' when 2 then 'Mon' when 3 then 'Tue' when 4 then 'Wed' when 5 then 'Thu' when 6 then 'Fri' when 7 then 'Sat' else null end, START_OF_WEEK = convert(varchar(10),dbo.F_START_OF_WEEK( a.DT, b.number ),121), START_DW = left(datename(dw,dbo.F_START_OF_WEEK( a.DT, b.number )),3), END_OF_WEEK = convert(varchar(10),dbo.F_END_OF_WEEK( a.DT, b.number ),121), EOW_DW = left(datename(dw,dbo.F_END_OF_WEEK( a.DT, b.number )),3)from ( -- Get dates from end of datetime range select DT = dateadd(dd,a1.number,'9999-12-25') from dbo.F_TABLE_NUMBER_RANGE(0,6) a1 union all -- Get some normal dates, +/- 10 day from current date select DT = dateadd(dd,a3.number,getdate()) from dbo.F_TABLE_NUMBER_RANGE(-10,10) a3 union all -- Get dates from beginning of datetime range select DT = dateadd(dd,a2.number,'17530101') from dbo.F_TABLE_NUMBER_RANGE(0,6) a2 ) a cross join dbo.F_TABLE_NUMBER_RANGE(1,7) border by a.dt, b.number/*End of test script*/
Edit 2010-11-12:This code shows an inline code solution for any ending day of week, Sunday through Saturday. It will work for any date within the range of 1753-01-08 through 9999-12-24select a.DT, EOWSun = dateadd(dd,((datediff(dd,-53690,a.DT)/7)*7)+6,-53690), EOWMon = dateadd(dd,((datediff(dd,-53689,a.DT)/7)*7)+6,-53689), EOWTue = dateadd(dd,((datediff(dd,-53688,a.DT)/7)*7)+6,-53688), EOWWed = dateadd(dd,((datediff(dd,-53687,a.DT)/7)*7)+6,-53687), EOWThu = dateadd(dd,((datediff(dd,-53686,a.DT)/7)*7)+6,-53686), EOWFri = dateadd(dd,((datediff(dd,-53685,a.DT)/7)*7)+6,-53685), EOWSat = dateadd(dd,((datediff(dd,-53684,a.DT)/7)*7)+6,-53684)from ( -- Generate test data dates select DT = dateadd(dd,aa.number,'20100101') from -- Number Table Function available here -- http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=47685 dbo.F_TABLE_NUMBER_RANGE(0,365) aa ) aorder by a.DT
Alternative inline code using date strings instead of representing dates as numbers:select a.DT, EOWSun = dateadd(dd,((datediff(dd,'17530101',a.DT)/7)*7)+6,'17530101'), EOWMon = dateadd(dd,((datediff(dd,'17530102',a.DT)/7)*7)+6,'17530102'), EOWTue = dateadd(dd,((datediff(dd,'17530103',a.DT)/7)*7)+6,'17530103'), EOWWed = dateadd(dd,((datediff(dd,'17530104',a.DT)/7)*7)+6,'17530104'), EOWThu = dateadd(dd,((datediff(dd,'17530105',a.DT)/7)*7)+6,'17530105'), EOWFri = dateadd(dd,((datediff(dd,'17530106',a.DT)/7)*7)+6,'17530106'), EOWSat = dateadd(dd,((datediff(dd,'17530107',a.DT)/7)*7)+6,'17530107')from ( -- Generate test data dates select DT = dateadd(dd,aa.number,'20100101') from -- Number Table Function available here -- http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=47685 dbo.F_TABLE_NUMBER_RANGE(0,365) aa ) aorder by a.DT
Alternative inline code 2 using date strings and eliminating +6 by selecting second date six days later.select a.DT, EOWSun = dateadd(dd,((datediff(dd,'17530101',a.DT)/7)*7),'17530107'), EOWMon = dateadd(dd,((datediff(dd,'17530102',a.DT)/7)*7),'17530108'), EOWTue = dateadd(dd,((datediff(dd,'17530103',a.DT)/7)*7),'17530109'), EOWWed = dateadd(dd,((datediff(dd,'17530104',a.DT)/7)*7),'17530110'), EOWThu = dateadd(dd,((datediff(dd,'17530105',a.DT)/7)*7),'17530111'), EOWFri = dateadd(dd,((datediff(dd,'17530106',a.DT)/7)*7),'17530112'), EOWSat = dateadd(dd,((datediff(dd,'17530107',a.DT)/7)*7),'17530113')from ( -- Generate test data dates select DT = dateadd(dd,aa.number,'20100101') from -- Number Table Function available here -- http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=47685 dbo.F_TABLE_NUMBER_RANGE(0,365) aa ) aorder by a.DT
CODO ERGO SUM