Reputation: 2143
I have this query to pull the last friday date with given a date. It works for all day except if the given date is today.
select dateadd(d, -((datepart(weekday, getdate()) + 1 + @@DATEFIRST) % 7), getdate())
Taking for example, today is 2014-02-14. if i apply to the query above, the result returned is still 2014-02-14
dateadd(d, -((datepart(weekday, '2014-02-14') + 1 + @@DATEFIRST) % 7), '2014-02-14')
If i put as 2014-02-13 below, then it returned last friday date properly.
select dateadd(d, -((datepart(weekday, '2014-02-13') + 1 + @@DATEFIRST) % 7), '2014-02-13')
Can you help how i can i get last Friday date if given today is Friday.
Upvotes: 2
Views: 7236
Reputation: 69759
Your first attempt seems pretty close, I think you just need to move the 1 to outside of the modulo function. This works for me:
SELECT DATEADD(DAY, -1 - ((DATEPART(WEEKDAY, GETDATE()) + @@DATEFIRST) % 7), CAST(GETDATE() AS DATE));
Then tested on a larger sample it still seems to work:
DECLARE @T TABLE (DateFirst INT, Date DATE, LastFriday DATE)
DECLARE @I INT = 1;
WHILE @I < 8
BEGIN
SET DATEFIRST @i;
WITH TestDates AS
( SELECT Date = DATEADD(DAY, -Number, CAST(GETDATE() AS DATE))
FROM master..spt_values
WHERE Type = 'P'
AND Number BETWEEN 0 AND 20
)
INSERT @T (DateFirst, Date, lastFriday)
SELECT @I,
Date,
LastFriday = DATEADD(DAY, -1 - ((DATEPART(WEEKDAY, Date) + @@DATEFIRST) % 7), Date)
FROM TestDates;
SET @i += 1;
END
SELECT *
FROM @T
PIVOT
( MAX(LastFriday)
FOR DateFirst IN ([1], [2], [3], [4], [5], [6], [7])
) pvt
ORDER BY Date;
This works for all language and datefirst settings.
If you can control your datefirst settings this becomes simpler:
SET DATEFIRST 6;
SELECT DATEADD(DAY, -DATEPART(WEEKDAY, GETDATE()), CAST(GETDATE() AS DATE))
However I would always recommend making your queries safe against local settings.
Upvotes: 3
Reputation: 2989
You can check to see if the current day is Friday with DATENAME
and if so, just subtract 7 days, otherwise, use the function you made
SELECT CASE WHEN DATENAME(WEEKDAY, GETDATE()) = 'Friday' THEN
CONVERT(DATE, DATEADD(DAY, -7, GETDATE()))
ELSE
DATEADD(d, -((DATEPART(WEEKDAY, GETDATE()) + 1 + @@DATEFIRST) % 7), GETDATE())
END AS 'LastFriday'
Upvotes: 7
Reputation: 1269563
How about a brute force approach:
select dateadd(day,
(case when datename(weekday, getdate()) = 'Friday' then -7
when datename(weekday, getdate()) = 'Saturday' then -1
when datename(weekday, getdate()) = 'Sunday' then -2
when datename(weekday, getdate()) = 'Monday' then -3
when datename(weekday, getdate()) = 'Tuesday' then -4
when datename(weekday, getdate()) = 'Wednesday' then -5
when datename(weekday, getdate()) = 'Thursday' then -6
end),
cast(getdate() as date)
);
This does the logic for today. You can replace all the getdate()
references with another date for another date.
Upvotes: 3