18

I'm trying to get the most recent Friday in SQL Server 2008.

I have this. It gets the beginning of the week (monday) then subtracts 3 days to get Friday.

declare @recentFriday datetime =  DATEADD(ww, DATEDIFF(dd,0,GETDATE()), 0)-3

When this is run during the week, it gets last Friday's date which is correct. But when run on Friday (or Saturday), it still gets last week's date instead of the current week's Friday. I'm about to use if/else conditions but I'm sure there's an easier way.

Gabe
  • 5,113
  • 11
  • 55
  • 88
James
  • 506
  • 2
  • 6
  • 15
  • 1
    possible duplicate of [Find last sunday](http://stackoverflow.com/questions/1794697/find-last-sunday). Similar to Joe's answer – gbn May 14 '11 at 09:01

8 Answers8

17

This works for any input and any setting of DATEFIRST:

dateadd(d, -((datepart(weekday, getdate()) + 1 + @@DATEFIRST) % 7), getdate())

It works by adjusting the weekday value so that 0 = Friday, simulating Friday as the beginning of the week. Then subtract the weekday value if non-zero to get the most recent Friday.

Edit: Updated to work for any setting of DATEFIRST.

mellamokb
  • 56,094
  • 12
  • 110
  • 136
  • i am not downvote, but I think which the downvote was before which you edit your question. – RRUZ May 13 '11 at 22:12
  • Hi @mellamokb, I'm intrigued by this line of code you have posted. I have a scenario where I may have to use it so that in one script I may have to find the most recent Thurs, or in another the most recent Monday. What do I have to change in your code so that I have that level of flexibility? Do I just change the "+1" to "+2" to pick up the most recent Thurs for instance? How does your code make Friday = 0? – chrissy p Oct 30 '13 at 09:42
  • 2
    Its the middle value that does it (the +1) Here's a more generalized version with some test variables that you can play around with that hopefully will illustrate: `DECLARE @DayToFind varchar(10), @DwValue int, @DateToTestWith datetime; SELECT @DayToFind = 'fri', @DateToTestWith = DATEADD(dd, 0, GetDate()); SELECT @DwValue = CHARINDEX(SUBSTRING(@DayToFind,1,3), 'FRITHUWEDTUEMONSUNSAT') / 3 + 1; SELECT dateadd(d, -((datepart(weekday, @DateToTestWith) + @DwValue + @@DATEFIRST) % 7), @DateToTestWith);` Try changing the @DayToFind or the @DateToTestWith. – Brian Swift Dec 15 '15 at 00:10
  • I cannot for the life of me figure out what `@@DATEFIRST` is supposed to be. Is it a number? A date? What date? – Martha Mar 14 '17 at 20:13
  • @Martha: Check out the documentation [here](https://msdn.microsoft.com/en-us/library/ms187766.aspx), should answer all your questions. It's necessary in case some SQL Server instances have custom first day of the week. – mellamokb Mar 14 '17 at 20:16
6
DECLARE @date DATETIME = '20110512' -- Thursday
SELECT DATEADD(DAY,-(DATEDIFF(DAY,'19000105',@date)%7),@date) --20110506

SET @date = '20110513' -- Friday
SELECT DATEADD(DAY,-(DATEDIFF(DAY,'19000105',@date)%7),@date) --20110513

SET @date = '20110514' -- Saturday
SELECT DATEADD(DAY,-(DATEDIFF(DAY,'19000105',@date)%7),@date) --20110513
  1. Calculate the number of days between a known Friday (05 Jan 1900) and the given date
  2. The remainder left from dividing the difference in 1. by 7 will be the days elapsed since the last Friday
  3. Subtract the remainder in 2. from the given date
Pero P.
  • 25,813
  • 9
  • 61
  • 85
4

you can check if the current day of week is friday or greater DATEPART(dw,GETDATE()) and then call (SELECT DATEADD(wk, DATEDIFF(wk,0,GETDATE()), 0)+4) or (SELECT DATEADD(wk, DATEDIFF(wk,0,GETDATE()), 0)-3)

SELECT 
CASE WHEN DATEPART(dw,GETDATE()) >= 5 THEN 
(SELECT DATEADD(wk, DATEDIFF(wk,0,GETDATE()), 0)+4) 
ELSE 
(SELECT DATEADD(wk, DATEDIFF(wk,0,GETDATE()), 0)-3) 
END
RRUZ
  • 134,889
  • 20
  • 356
  • 483
  • This is dependant upon `@@DATEFIRST` settings. If I try `SET DATEFIRST 2` it returns `2011-05-06`, For `SET DATEFIRST 1` it returns `2011-05-13` – Martin Smith May 13 '11 at 21:59
  • @Martin, I Agree with you, but the OP easily can add that variable into the SQL proposed. – RRUZ May 13 '11 at 22:02
3

Using a known Friday date (I'll use Jan 7, 2011) as a starting point, you can do this:

DECLARE @d DATETIME

SET @d = '2011-05-13' /* Friday */
SELECT DATEADD(DAY, (DATEDIFF (DAY, '20110107', @d) / 7) * 7, '20110107')
/* Returns 2011-05-13 */

SET @d = '2011-05-12' /* Thursday */
SELECT DATEADD(DAY, (DATEDIFF (DAY, '20110107', @d) / 7) * 7, '20110107')
/* Returns 2011-05-06 */

Just choose a known Friday that's older than any dates you'll be using in your calculations.

Joe Stefanelli
  • 132,803
  • 19
  • 237
  • 235
1
SELECT CONVERT(VARCHAR(12),GETDATE()) AS Today,
CASE WHEN (DATEPART(DW,GETDATE())< 7) 
THEN CONVERT(VARCHAR(12),(DATEADD(dd,-(DATEPART(DW,GETDATE())+1),GETDATE())))
ELSE CONVERT(VARCHAR(12),(DATEADD(d,- 1,GETDATE())))
END AS [Last Friday]
suman
  • 124
  • 5
1

The other solutions were not working for my use case.

This works for finding any previous day by replacing 'Sunday' with the day you`re looking for:

    DECLARE @myDate DATE = GETDATE()

    WHILE DATENAME(WEEKDAY, @myDate) <> 'Sunday'
    BEGIN
        SET @myDate = DATEADD(DAY, -1, @myDate)
    END
theduck
  • 2,589
  • 13
  • 17
  • 23
1

Here is a completly set oriented way to achive the last Friday:

select Friday from
(
select max(GetDate()) as Friday where datepart(dw, getdate()) = 6
union all
select max((GetDate() - 1)) where datepart(dw, (getdate() - 1)) = 6
union all
select max((GetDate() - 2)) where datepart(dw, (getdate() - 2)) = 6
union all
select max((GetDate() - 3)) where datepart(dw, (getdate() - 3)) = 6
union all
select max((GetDate() - 4)) where datepart(dw, (getdate() - 4)) = 6
union all
select max((GetDate() - 5)) where datepart(dw, (getdate() - 5)) = 6
) x where Friday is not null
fancyPants
  • 50,732
  • 33
  • 89
  • 96
Scott Bruns
  • 1,971
  • 12
  • 12
0

This is what I got I hope it helps

DECLARE @UserDate DateTime
SET @UserDate = '2020-09-03'
SELECT DATEADD(day, (6 - datepart(weekday, @UserDate)) , @UserDate)
drops
  • 1,524
  • 1
  • 11
  • 20
amir
  • 1