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.
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.
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
Calculate the number of days between a known Friday (05 Jan 1900) and the given date
The remainder left from dividing the difference in 1. by 7 will be the days elapsed since the last Friday
Subtract the remainder in 2. from the given date
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
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.
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]
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
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
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)
Related
hello I was looking to execute a stored procedure that receives variables for #startweek and #endweek.
I wanted to pass for execution that the #endweek to be the last friday of the current week and for the #startweek to be the friday of 6 weeks ago.
I have made the following for the last friday of current week:
SELECT #startweek = '25 Jan 2019'
SELECT #endweek = DATE
FROM
(SELECT DATE = dateadd(d, -((datepart(weekday, getdate()) + 1 + ##DATEFIRST) % 7), getdate())) a
ORDER BY a.DATE DESC
What I'm needing to do is to get the way to pass the #endweek value (now is hardcoded) for it to select the last friday of 6 weeks ago.
one thing that I got to work is the following:
SELECT friday4WeeksAgo =dateadd(ww, -4,DATE)
FROM
(SELECT DATE = dateadd(d, -((datepart(weekday, getdate()) + 1 + ##DATEFIRST) % 7), getdate())) a
ORDER BY a.DATE DESC
but I wasn't able to pass this to a variable
I have the procedure written, just need to figure out how to do to pass to these variable the values that I need (#startweek and #endweek) to show the last friday from 6 weeks ago and the last friday from current week
thank you for any help
Your calculation for last Friday is correct, but unnecessarily complicated.
SELECT #endweek = dateadd(d, -((datepart(weekday, getdate()) + 1 + ##DATEFIRST) % 7), getdate());
SELECT #startweek = DATEADD(WEEK, -6, #endweek)
EXEC YourProcedure
#StartWeek = #startweek,
#EndWeek = #endweek;
Is that what you were looking for?
This should work
DECLARE #startweek DATE,#endweek DATE
SET #startweek = '14 Aug 2019'
SET #endweek = dateadd(day,case when DATEPART(DW,dateadd(ww,-6,#startweek))>5 then 6 else -1 end -
DATEPART(DW,dateadd(ww,-6,#startweek)), dateadd(ww,-6,#startweek))
SELECT #startweek AS DatePassedIn,
#endweek AS Six_weeks_ago_Friday_Date
--dateadd(ww,-6,#startweek)/*this part get 6 weeks back, based on date pass to #startweek*/
In SQL Server 2008 i want to set a default date value of every Friday to show up in the column when i insert a new record?
ALTER TABLE myTable ADD CONSTRAINT_NAME DEFAULT GETDATE() FOR myColumn
Whats the best way to show every Friday?
I want the default value to be based on the now date then knowing that the next available date is 05-07/2013
I have the following:
dateadd(d, -((datepart(weekday, getdate()) + 1 + ##DATEFIRST) % 7), getdate())
But when passing todays date, it gave me: 2013-06-28 which is actually LAST Friday!, it should be the up and coming Friday!
SELECT DATEADD(day,-3, DATEADD(week, DATEDIFF(week, 0, current_timestamp)+1, 0)) AS LastFridayDateOfWeek
Gets the last date of current week (sunday) then subtracts 3 from that to get Friday.
Replace current_timestamp if you need a different dates friday.
EDIT:
I thought about this a bit, and if the above (Friday THIS WEEK, so for Saturday it gives the previous date) does not work, you could easily use a reference date set like so:
DATEADD(DAY,7 + DATEDIFF(day,'20100109',#checkDateTime)/7*7,'20100108') as FridayRefDate
Same thing but with no hard coded Friday/Saturday in it:
DATEADD(DAY,7 + DATEDIFF(day,DATEADD(wk, DATEDIFF(wk,0,#checkDateTime),5),#checkDateTime)/7*7,DATEADD(wk, DATEDIFF(wk,0,#checkDateTime), 4))
So for 20100109 is a Friday.
SET #checkDateTime = '2012-01-14 3:34:00.000'
SELECT DATEADD(DAY,7 + DATEDIFF(day,'20100109',#checkDateTime)/7*7,'20100108') as FridayRefDate
it returns "2012/1/20"
But for SET #checkDateTime = '2012-01-13 3:34:00.000' it returns "2012/1/13"
If your current query gives you last Friday, the easiest thing to do is simply to add 7 to it:
select dateadd(d, 7-((datepart(weekday, getdate()) + 1 + ##DATEFIRST) % 7), getdate())
------------------^
SELECT CONVERT(DATE, ( CASE WHEN DATEPART(dw, GETDATE()) - 6 <= 0
THEN DATEADD(dd,
( DATEPART(dw, GETDATE()) - 6 ) * -1,
GETDATE())
ELSE DATEADD(dd, ( DATEPART(dw, GETDATE()) ) - 1,
GETDATE())
END )) AS NearestFriday
Just add 7 to the formula
SELECT DATEADD(dd,CAST(5-GETDATE() AS int)%7,GETDATE()+7)
To verify the formula:
WITH test AS (
SELECT GETDATE() AS d UNION ALL
SELECT DATEADD(dd,1,d)
FROM test WHERE d < GETDATE() + 30
)
SELECT
d AS [input],
DATEADD(dd,CAST(5-d AS int)%7,d+7) AS [output]
FROM test
To tweak the the formula, adjust the 5- and the +7
I'm trying to get the correct SQL code to obtain last Friday's date. A few days ago, I thought I had my code correct. But just noticed that it's getting last week's Friday date, not the last Friday. The day I'm writing this question is Saturday, 8/11/2012 # 12:23am. In SQL Server, this code is returning Friday, 8/3/2012. However, I want this to return Friday, 8/10/2012 instead. How can I fix this code? Since we're getting to specifics here, if the current day is Friday, then I want to return today's date. So if it were yesterday (8/10/2012) and I ran this code yesterday, then I would want this code to return 8/10/2012, not 8/3/2012.
SELECT DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()), 0))
try this:
declare #date datetime;
set #date='2012-08-09'
SELECT case when datepart(weekday, #date) >5 then
DATEADD(DAY, +4, DATEADD(WEEK, DATEDIFF(WEEK, 0, #date), 0))
else DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, #date), 0)) end
result:
2012-08-03
Example2:
declare #date datetime;
set #date='2012-08-10'
SELECT case when datepart(weekday, #date) >5 then
DATEADD(DAY, +4, DATEADD(WEEK, DATEDIFF(WEEK, 0, #date), 0))
else DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, #date), 0)) end
result:
2012-08-10
Modular arithmetic is the most direct approach, and order of operations decides how Fridays are treated:
DECLARE #test_date DATETIME = '2012-09-28'
SELECT DATEADD(d,-1-(DATEPART(dw,#test_date) % 7),#test_date) AS Last_Friday
,DATEADD(d,-(DATEPART(dw,#test_date+1) % 7),#test_date) AS This_Friday
Use this :
SELECT DATEADD(day, (DATEDIFF (day, '19800104', CURRENT_TIMESTAMP) / 7) * 7, '19800104') as Last_Friday
None of that? Try this:
DECLARE #D DATE = GETDATE()
SELECT DATEADD(D,-(DATEPART(W,#D)+1)%7,#D)
A tested function which works no matter what ##DATEFIRST is set to.
-- ==============
-- fn_Get_Week_Ending_forDate
-- Author: Shawn C. Teague
-- Create date: 2017
-- Modified date:
-- Description: Returns the Week Ending Date on DayOfWeek for a given stop date
-- Parameters: DayOfWeek varchar(10) i.e. Monday,Tues,Wed,Friday,Sat,Su,1-7
-- DateInWeek DATE
-- ==============
CREATE FUNCTION [dbo].[fn_Get_Week_Ending_forDate] (
#DayOfWeek VARCHAR(10),#DateInWeek DATE)
RETURNS DATE
AS
BEGIN
DECLARE #End_Date DATE
,#DoW TINYINT
SET #DoW = CASE WHEN ISNUMERIC(#DayOfWeek) = 1
THEN CAST(#DayOfWeek AS TINYINT)
WHEN #DayOfWeek like 'Su%' THEN 1
WHEN #DayOfWeek like 'M%' THEN 2
WHEN #DayOfWeek like 'Tu%' THEN 3
WHEN #DayOfWeek like 'W%' THEN 4
WHEN #DayOfWeek like 'Th%' THEN 5
WHEN #DayOfWeek like 'F%' THEN 6
ELSE 7
END
select #End_Date =
CAST(DATEADD(DAY,
CASE WHEN (#DoW - (((##datefirst) + datepart(weekday, #DateInWeek)) % 7)) = 7
THEN 0
WHEN (#DoW - (((##datefirst) + datepart(weekday, #DateInWeek)) % 7)) < 0
THEN 7 - ABS(#DoW - (((##datefirst) + datepart(weekday, #DateInWeek)) % 7))
ELSE (#DoW - (((##datefirst) + datepart(weekday, #DateInWeek)) % 7) )
END
,#DateInWeek) AS DATE)
RETURN #End_Date
END
This will give you the Friday of Last week.
SELECT DATEADD(day, -3 - (DATEPART(dw, GETDATE()) + ##DATEFIRST - 2) % 7, GETDATE()) AS LastWeekFriday
This will give you last Friday's Date.
SELECT DATEADD(day, +4 - (DATEPART(dw, GETDATE()) + ##DATEFIRST-2) % 7, GETDATE()) AS LastFriday
select convert(varchar(10),dateadd(d, -((datepart(weekday, getdate()) + 1 + ##DATEFIRST) % 7), getdate()),101)
Following code can be use to return any last day by replacing #dw_wk, test case below use friday as asked in original questions
DECLARE #date SMALLDATETIME
,#dw_wk INT --last day of week required - its integer representation
,#dw_day int --current day integer reprsentation
SELECT #date='8/11/2012'
SELECT #dw_day=DATEPART(dw,#date)
SELECT #dw_wk=DATEPART(dw,'1/2/2015') --Just trying not to hard code 5 for friday, here we can substitute with any date which is friday
SELECT case when #dw_day<#dw_wk then DATEADD(DAY, #dw_wk-7-#dw_day,#date) else DATEADD(DAY,#dw_wk-#dw_day, #date) END
Here's an answer I found here adapted from MySQL to T-SQL that is a one liner using all basic arithmetic (no division or modulos):
SELECT DATEADD(d, 1 - datepart(weekday, dateadd(d, 2, GETDATE())), GETDATE())
You can do all sorts of combinations of this, like get next Friday's date unless today is Friday, or get last Thursday's date unless today is Thursday by just changing the 1 and the 2 literals in the command:
Get next Friday's date unless today is Friday
SELECT DATEADD(d, 7 - datepart(weekday, dateadd(d, 1, GETDATE())), GETDATE())
Get last Thursday's date unless today is Thursday
SELECT DATEADD(d, 1 - datepart(weekday, dateadd(d, 3, GETDATE())), GETDATE())
I have had this same issue, and created the following example to show how to do this and to make it flexible to use whichever day of the week you want. I have different lines in the SELECT statement, just to show what this is doing, but you just need the [Results] line to get the answer. I also used variables for the current date and the target day of the week, to make it easier to see what needs to change.
Finally, there is an example of results when you want to include the current date as a possible example or when you always want to go back to the previous week.
DECLARE #GetDate AS DATETIME = GETDATE();
DECLARE #Target INT = 6 -- 6 = Friday
SELECT
#GetDate AS [Current Date] ,
DATEPART(dw, #GetDate) AS [Current Day of Week],
#Target AS [Target Day of Week] ,
IIF(#Target = DATEPART(dw, #GetDate), 'Yes' , 'No') AS [IsMatch] ,
IIF(#Target = DATEPART(dw, #GetDate), 0 , ((7 + #Target - DATEPART(dw, #GetDate)) % 7) - 7) AS [DateAdjust] ,
------------------------------------------------------------------------------------------------------------------------------------------------
CAST(IIF(#Target = DATEPART(dw, #GetDate), #GetDate, DATEADD(d, (((7 + #Target - DATEPART(dw, #GetDate)) % 7) - 7), #GetDate)) AS DATE) AS [Result]
------------------------------------------------------------------------------------------------------------------------------------------------
;
SELECT
#GetDate AS [Current Date] ,
DATEPART(dw, #GetDate) AS [Current Day of Week],
#Target AS [Target Day of Week] ,
((7 + #Target - DATEPART(dw, #GetDate)) % 7) - 7 AS [DateAdjust] ,
------------------------------------------------------------------------------------------------------------------------------------------------
CAST(DATEADD(d, (((7 + #Target - DATEPART(dw, #GetDate)) % 7) - 7), #GetDate) AS DATE) AS [NOTIncludeCurrent]
------------------------------------------------------------------------------------------------------------------------------------------------
;
SELECT DECODE(TO_CHAR(SYSDATE,'DY'),'FRI',SYSDATE,NEXT_DAY(SYSDATE, 'FRI')-7) FROM dual;
How to get Saturday's Date. I have today's date with me.
GETDATE()
How to do this.
For eg. TODAY is 08-08-2011
I want output as 08-13-2011
This is a function that will return the next Saturday if you call it like this:
SELECT dbo.fn_Get_NextWeekDay('2011-08-08', 6)
The "6" comes from the list of possible values you can set for DATEFIRST.
You can get any other day of the week by changing the second parameter accordingly.
This is the function:
IF OBJECT_ID('dbo.fn_Get_NextWeekDay') IS NOT NULL
DROP FUNCTION dbo.fn_Get_NextWeekDay
GO
CREATE FUNCTION dbo.fn_Get_NextWeekDay(
#aDate DATETIME
, #dayofweek INT
/*
#dw - day of the week
1 - Monday
2 - Tuesday
3 - Wednesday
4 - Thursday
5 - Friday
6 - Saturday
7 - Sunday
*/
)
RETURNS DATETIME
AS
/*
SELECT dbo.fn_Get_NextWeekDay('2011-08-08', 6)
SELECT dbo.fn_Get_NextWeekDay('2011-08-08', 1)
*/
BEGIN
RETURN
DATEADD(day
, ( #dayofweek + 8 - DATEPART(dw, #aDate) - ##DATEFIRST ) % 7
, #aDate
)
END
GO
[EDIT]
This might be another solution. This should work in any language:
IF OBJECT_ID('dbo.fn_NextWeekDay') IS NOT NULL
DROP FUNCTION dbo.fn_NextWeekDay
GO
CREATE FUNCTION dbo.fn_NextWeekDay(
#aDate DATE
, #dayofweek NVARCHAR(30)
)
RETURNS DATE
AS
/*
SELECT dbo.fn_NextWeekDay('2016-12-14', 'fri')
SELECT dbo.fn_NextWeekDay('2016-03-15', 'mon')
*/
BEGIN
DECLARE #dx INT = 6
WHILE UPPER(DATENAME(weekday,#aDate)) NOT LIKE UPPER(#dayofweek) + '%'
BEGIN
SET #aDate = DATEADD(day,1,#aDate)
SET #dx=#dx-1
if #dx < 0
BEGIN
SET #aDate = NULL
BREAK
END
END
RETURN #aDate
END
GO
Use DATEPART to get the day of week of today and add the difference to the desired day of week to todays date.
DECLARE #Today date = 'TODAYS-DATE';
DECLARE #TodayNumber int = DATEPART(dw, #Today) -- Get the day number
DECLARE #Saturday date = DATEADD(DAY, (6-#TodayNumber)%7, #Today)
-- Add the number of days between today and saturday (the 6th day), modulus 7 to stop you adding negative days
Hope that helps!
Use a Calendar table (table with one row per date):
SELECT MIN(DateValue) DateValue
FROM Calendar
WHERE DateValue >= CURRENT_TIMESTAMP
AND DayOfWeek = 'Saturday';
Another approach to this takes two steps, but might be more readable (look ma, no modulus):
Go back to last saturday: DATEADD(DAY, -1 * datepart(weekday, GETDATE()), getdate())
Then, add on a week: DATEADD(WEEK, 1, #lastSaturday, getdate()))
The whole thing:
declare #today DATETIME = GETDATE()
declare #lastSaturday DATETIME = DATEADD(DAY, -1 * datepart(weekday, #today), #today)
declare #nextSaturday DATETIME = DATEADD(WEEK, 1, #lastSaturday)
Or, if you're ok with #today being GETDATE(), you can do the calculation all at once:
SELECT DATEADD(WEEK, 1, DATEADD(DAY, -1 * datepart(weekday, GETDATE()), getdate()))
Checkout the SQL DATEADD function.
DATEADD (Transact-SQL)
Which you can use this along with DATEPART function to return the correct date.
DATEPART (Transact-SQL)
Try this :
SET DATEFIRST 7
DECLARE #d DATETIME
SET #d = '2011-08-08' --GETDATE()
SELECT NEXT_SAT = DATEADD(day, (7 + ##DATEFIRST - DATEPART(dw, #d)) % 7, #d )
declare #Curdate date=( SELECT SWITCHOFFSET(SYSDATETIMEOFFSET(),'+05:30') )
declare #nextsaturdaydate date=(select dateadd(d, 7-datepart(WEEKDAY, #CurDate),#Curdate))
select #nextsaturdaydate
Please let me know how can I find if it is Sunday on given Date?
EDIT:
From answers another thing comes to my mind: How to find what is first day of week?
Use the "datename" function:
print datename(weekday, '11/29/2009')
or with a variable:
declare #date smalldatetime
set #date = '12/25/2008'
select datename(weekday, #date)
SELECT DATEPART(dw,theDateRow) AS dateOfWeek FROM someTable
dw stands for Day of Week
if dw = 0, it is Sunday.
A) Sunday Check
SELECT
CASE WHEN DATENAME(WEEKDAY, GETDATE()) != 'Sunday'
Then 'It is ' + CAST(DATENAME(WEEKDAY, GETDATE()) AS VARCHAR(10))
Else 'It is ' + CAST(DATENAME(WEEKDAY, GETDATE()) AS VARCHAR(10))
END 'Day is'
Output:
Day is
It is Saturday
B) Find first day of week
SELECT
DayName = DATENAME(WEEKDAY,
DATEADD(DD, 1 - DATEPART(DW, CONVERT(VARCHAR(10), GETDATE(), 111)),
CONVERT(VARCHAR(10), GETDATE(), 111))),
Date = DATEADD(DD,
1 - DATEPART(DW, CONVERT(VARCHAR(10), GETDATE(), 111)),
CONVERT(VARCHAR(10), GETDATE(), 111))
Output:
DayName Date
Sunday 2009-12-27 00:00:00.000
To find what is the first day of the week you use:
print ##datefirst
This will return a number from 1 to 7, where 1 = Monday, 2 = Tuesday... 7 = Sunday. You can change what is considered the first day of the week (on the SQL instance) by using:
set datefirst = 1
This will set the first day to Monday. By default SQL is set to 7 (Sunday) in US.