Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
mapidea
Posting Yak Master
124 Posts |
Posted - 2015-05-06 : 09:05:54
|
Is there a better way to write the function?Getting the Last Thursday of the month from the date given. If the last Thursday has passed then find the last Thursday of next month.ALTER FUNCTION [dbo].[ufn_LastThursdayfromADate] ( -- Add the parameters for the function here @getDate Date)RETURNS DateASBEGIN DECLARE @LastThursdayfromADate DATE, @FirstDateOftheMonth DATE, @FirstDateOfNextMonth DATE; SET @FirstDateOftheMonth = DATEADD(dd,-(DAY(@getDate)-1),@getDate); SET @FirstDateOfNextMonth = DATEADD(dd,-(DAY(DATEADD(mm,1,@FirstDateOftheMonth))-1),DATEADD(mm,1,@FirstDateOftheMonth)); SELECT @LastThursdayfromADate = MAX(Thursdaydate) FROM ( select dateadd(day,number,@FirstDateOftheMonth) AS Thursdaydate FROM master..spt_values where type='p' and number<32 ) t WHERE datename(weekday,Thursdaydate) = 'thursday' IF(@LastThursdayfromADate <= @getDate) BEGIN SELECT @LastThursdayfromADate = MAX(Thursdaydate) FROM ( select dateadd(day,number,@FirstDateOfNextMonth) AS Thursdaydate FROM master..spt_values where type='p' and number<32 ) t WHERE datename(weekday,Thursdaydate) = 'thursday' END RETURN @LastThursdayfromADate;END |
|
Kristen
Test
22859 Posts |
Posted - 2015-05-06 : 09:47:34
|
[code]DECLARE @getDate Date = '20150101' -- A Test ValueDECLARE @LastThursdayfromADate date, @FirstDateOfNextMonth date, @intWeekday intSELECT @FirstDateOfNextMonth = DATEADD(Month, DATEDIFF(Month, 0, @getDate)+1, 0), @intWeekday = DATEPART(Weekday, @FirstDateOfNextMonth), @LastThursdayfromADate = DATEADD(Day, 5 - @intWeekday - CASE WHEN @intWeekday <= 5 THEN 7 ELSE 0 END, @FirstDateOfNextMonth)-- Display workings and result:SELECT [@FirstDateOfNextMonth] = @FirstDateOfNextMonth, [@intWeekday] = @intWeekday, [@LastThursdayfromADate] = @LastThursdayfromADate, [Weekday] = DATENAME(Weekday, @LastThursdayfromADate)[/code]I think "first day of week" is configurable, in SQL, so would have to watch out in case that is set to something non-standard |
|
|
Kristen
Test
22859 Posts |
Posted - 2015-05-06 : 09:49:35
|
I expect there is a way to do this with CTE or APPLY to save having to have intermediate storage of @FirstDateOfNextMonth & @intWeekday (and to avoid having to specify them twice!)I've seen solutions based on using a TALLY table, but it seems unnecessary to me to use a table lookup as this is just integer maths, which I assume?? is quicker. |
|
|
mapidea
Posting Yak Master
124 Posts |
Posted - 2015-05-06 : 11:09:03
|
Thank you for your reply.You have used CASE statement to make it simple.IF(@LastThursdayfromADate <= @getDate)How can we get the Last Thursday from Next month? |
|
|
gbritton
Master Smack Fu Yak Hacker
2780 Posts |
Posted - 2015-05-06 : 11:28:13
|
SET DATEFIRST affects the algorithm. Here's a version that takes that into account:SELECT TestDate, Date1st, offset, FirstDateOfNextMonth, intWeekday, LastThursdayfromADate, datepart(weekday, LastThursdayfromADate) AS DayNumber, datename(weekday, LastThursdayfromADate) AS DayNameFROM ( VALUES ( @TestDate, @@DATEFIRST, -- compute the offset to Thursday for the current setting of DATEFIRST CASE WHEN @@DATEFIRST > 5 THEN @@DATEFIRST - 2 ELSE 5 - @@DATEFIRST END ) ) _1(TestDate, Date1st, offset)-- First day of next monthCROSS APPLY ( SELECT DATEADD(Month, DATEDIFF(Month, 0, TestDate) + 1, 0) ) _2(FirstDateOfNextMonth)-- Weekday number of first day of next monthCROSS APPLY ( SELECT DATEPART(Weekday, FirstDateOfNextMonth) ) _3(intWeekday)-- back up to last Thursday of preceding monthCROSS APPLY ( SELECT DATEADD(Day, offset - intWeekday - CASE WHEN intWeekday <= offset THEN 7 ELSE 0 END, FirstDateOfNextMonth) ) _4(LastThursdayfromADate); Note that all the APPLYs do not affect the final execution plan. The compiler inlines all the workGerald Britton, MCSAToronto PASS Chapter |
|
|
Kristen
Test
22859 Posts |
Posted - 2015-05-06 : 13:53:30
|
quote: Originally posted by mapidea How can we get the Last Thursday from Next month?
You need to understand the code, rather than blindly copying it - otherwise you won't be ale to support it Probably this (I haven't tested it)@FirstDateOfNextMonth = DATEADD(Month, DATEDIFF(Month, 0, @getDate)+2, 0)SELECT DATEADD(Month, DATEDIFF(Month, 0, TestDate) + 2, 0) |
|
|
MichaelJSQL
Constraint Violating Yak Guru
252 Posts |
Posted - 2015-05-06 : 13:55:18
|
you could use the following which is datefirst agnosticALTER FUNCTION [dbo].[ufn_LastThursdayfromADate] (@getDate Date)RETURNS DateASBEGINDECLARE @DTprimer datetime = DATEADD(dd,-DATEPART(dd,@getDate) +1,@getDate)DECLARE @LastThursdayfromADate DATE ;With myCal AS ( SELECT @DTprimer D UNION ALL SELECT DATEADD(dd,1,D) FROM myCal WHERE D< DATEADD(mm,2,@DTprimer) - 1 ) SELECT @LastThursdayfromADate = MIN(D) FROM (SELECT MAX(D) D FROM myCal WHERE DATENAME(dw,D) = 'Thursday' GROUP BY MONTH(D)) D WHERE D >= @getDate -- determine what you want to do if you pass the past thursday RETURN @LastThursdayfromADate;END-- testDECLARE @TestDate date = '5/29/2015'SELECT [dbo].[ufn_LastThursdayfromADate](@TestDate)SET @TestDate = '5/27/2015'SELECT [dbo].[ufn_LastThursdayfromADate](@TestDate) |
|
|
|
|
|
|
|