Reputation: 145
I have to get/create date from the user input of week of month (week number in that month - 1st,2nd,3rd,4th and last) and day of week (sunday,monday..) in SQL server.
Examples: 4th Sunday of every month, Last Friday of every month, First Monday etc.
I was able to do it easily in .net but SQL server does seem limited in the date functions.
I am having to use lot of logic to get the date. To calculate the date using the above two parameters I had to use lot of datepart function.
Any suggestions on how to come up with the optimal SQL query for such a function?
Upvotes: 3
Views: 3578
Reputation: 6713
Here is a general formula:
declare @month as datetime --set to the first day of the month you wish to use
declare @week as int --1st, 2nd, 3rd...
declare @day as int --Day of the week (1=sunday, 2=monday...)
--Second monday in August 2015
set @month = '8/1/2015'
set @week = 2
set @day = 2
select dateadd(
day,
((7+@day) - datepart(weekday, @month)) % 7 + 7 * (@week-1),
@month
)
You can also find the last, 2nd to last... etc with this reverse formula:
--Second to last monday in August 2015
set @month = '8/1/2015'
set @week = 2
set @day = 2
select
dateadd(
day,
-((7+datepart(weekday, dateadd(month,1,@month)-1)-@day)) % 7 - 7 * (@week-1),
dateadd(month,1,@month)-1
)
Upvotes: 1
Reputation: 69524
I created a function other day for another OP GET Month, Quarter based on Work Week number
This function takes the current year as default it can be further modified to take Year as a parameter too.
an extension to that function can produce the results you are looking for ....
WITH X AS
(
SELECT TOP (CASE WHEN YEAR(GETDATE()) % 4 = 0 THEN 366 ELSE 365 END)-- to handle leap year
DATEADD(DAY
,ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1
, CAST(YEAR(GETDATE()) AS VARCHAR(4)) + '0101' )
DayNumber
From master..spt_values
),DatesData AS(
SELECT DayNumber [Date]
,DATEPART(WEEKDAY,DayNumber) DayOfTheWeek
,DATEDIFF(WEEK,
DATEADD(WEEK,
DATEDIFF(WEEK, 0, DATEADD(MONTH,
DATEDIFF(MONTH, 0, DayNumber), 0)), 0)
, DayNumber- 1) + 1 WeekOfTheMonth
FROM X )
SELECT * FROM DatesData
WHERE DayOfTheWeek = 6 -- A function would expect these two parameters
AND WeekOfTheMonth = 4 -- @DayOfTheWeek and @WeekOfTheMonth
Upvotes: 1