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;
Related
I have a stored procedure that produces a report each night. This SP references a view that takes a snapshot of data from 2 weeks ago (Sunday to Saturday).
I need to get the dates of the Saturday and Sunday from two weeks ago (so for today that would be 23/24 of December.
I have searched through many solutions but I am unable to find a decent response to this - any one able to help with an answer as well as explaining a little bit of the reason for doing it that way (it seems like there are a thousand ways to do it).
Thanks
Here is the answer in case any one needs it in future.
SELECT DATEADD(wk, -2, DATEADD(wk, DATEDIFF(wk, 6, GETDATE()), 6))
Try this (for Saturday) is the same for Sunday:
DECLARE #today datetime
SET #today = GETDATE()
SELECT
CASE
WHEN DATENAME(weekday, #today) = 'Monday' THEN DATEADD(day, -15, #today)
WHEN DATENAME(weekday, #today) = 'Tuesday' THEN DATEADD(day, -16, #today)
WHEN DATENAME(weekday, #today) = 'Wednesday' THEN DATEADD(day, -17, #today)
WHEN DATENAME(weekday, #today) = 'Thursday' THEN DATEADD(day, -18, #today)
WHEN DATENAME(weekday, #today) = 'Friday' THEN DATEADD(day, -19, #today)
WHEN DATENAME(weekday, #today) = 'Saturday' THEN DATEADD(day, -13, #today)
WHEN DATENAME(weekday, #today) = 'Sunday' THEN DATEADD(day, -14, #today)
END
DATENAME with weekday parameter returns the name of the day, so if you are on Monday you must subtract 15 days to reach Saturday and so on.
Pay attention: If you have another language set you can change it for your query using:
SET LANGUAGE us_english
You can see SqlFiddle
Since the day of week value can differ on different machines you either need to set it using the set datefirst 1 command as suggeste in Podiluska's answer,
or you can do it by first determining the actual value for sunday and add that to the days you are subtracting.
To determine the actual value for sunday simply ask the value for a know sunday, like 2018-01-07 for example
Below example should return 2017-12-23 / 2017-12-24
It will also return this if you are running this on friday, or thursday, or whatever day...
-- this will contain are test date
declare #date date = getdate() - 2
-- determine the number for sunday
declare #Sunday int = (select datepart(dw, '20180107'))
select convert(date,dateadd(d, -15 - datepart(dw, #date) + (datepart(dw, #date) - #Sunday), getdate())),
convert(date,dateadd(d, -14 - datepart(dw, #date) + (datepart(dw, #date) - #Sunday), getdate()))
That depends on how you define when your week starts, but the basic principle is to find the start of this week, and take away 14 days.
eg:
set datefirst 1
select convert(date,dateadd(d, -15-datepart(dw, getdate()), getdate())),
convert(date,dateadd(d, -14-datepart(dw, getdate()), getdate()))
Sorry, I'll work on a general form for these; this is the quick and dirty.
I like the NEXT_DAY function. Simple, and obvious as to what it does.
declare
vFromDate date := trunc( sysdate ) - 9 ; -- '27 Feb 2019'
vSatDate date ;
vSunDate date ;
begin
-- test a range of dates
while vFromDate <= sysdate -- '3 Mar 2019'
loop
select NEXT_DAY ( TRUNC ( vFromDate) - 21, 'SAT') -- 7: general form for these?
-- keep or discard the " - 1" depending on if the 2 wk Sunday is the desired Sunday
, NEXT_DAY ( TRUNC ( vFromDate) - 20 - 1, 'SUN') -- 1:
into vSatDate, vSunDate
from dual ;
dbms_output.put_line( to_char( vFromDate, 'dd Mon": "' )
|| to_char( vSatDate, 'dd Mon' )
|| to_char( vSunDate, '", "dd Mon' )
);
vFromDate := vFromDate + 1 ;
end loop ;
dbms_output.put_line( rpad('*', 21, '*' ) );
end ;
How would I calculate the last weekday of the current month given a date using SQL?
I was able to get the last day of current month, but not sure how to do the last weekday programmatically.
I don't want to generate a calendar look-up table.
Here's the last day of month code i'm currently using:
declare #date datetime
set #date='1/4/13'
select DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, #date) + 1, 0))
Quite a neat solution:
declare #date1 as date = '20130401'
declare #date as date= eomonth(#date1,0)
set #date = (select case
when datepart(dw,#date) = 1 then dateadd(day,-2,#date) --when day is a sunday subtract 2 day to friday
when datepart(dw,#date) = 7 then dateadd(day,-1,#date) --when day is a saturday subtract 1 day to friday
else #date END)
I know that this is old, but I was looking for a one-liner and landed here. Here's the one I figured out:
set DATEFIRST 1
declare #testDate datetime
select #testDate = '8/1/2016'
select dateadd(day, -(select max(dayCount) from (values (DATEPART(WEEKDAY, EOMONTH(#testDate)) - 5), (0 )) as allDays(dayCount)), EOMONTH(#testDate))
This will only work with SQL Server 2012 and above.
How it works:
Get the last calendar date for the test date
Get the day-of-the week where Monday is 1, Saturday is 6 and Sunday
is 7
Subtract the day-of-the week and then set it to 0 if it is negative,
practically a max(0, day-of-the week - 5). This will leave 1 for Saturday or 2 for Sunday.
Subtract the days (1 if Saturday, 2 if Sunday) from the last day of
the month
I know it is not the most intuitive or effective or easy way of doing it. But here is my solution to find the last Weekday of the month...
declare #date datetime, #lastDate datetime, #lastWeekDay datetime
set #date='05/4/2014';--'1/1/2014'
set #lastDate = (SELECT DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, #date) + 1, 0)));
/* #dayOfWeek represents -- 0-Monday through 7-Sunday */
declare #dayOfWeek INT = (SELECT DATEDIFF(dd, 0, #lastDate) % 7);
/* If last date is sat/sun substract 1 or 2 days from last date */
set #lastWeekDay = (SELECT CASE WHEN #dayOfWeek = 5 THEN DATEADD(dd, -1, #lastDate)
WHEN #dayOfWeek = 6 THEN DATEADD(dd, -2, #lastDate)
ELSE #lastDate END)
SELECT #lastWeekDay;
This one is much harder than it ought to be. I’ve done similar work using datename, but only because I know all the systems I use will be configured with English as the default language. Without that assumption, you have to use datepart(dw, ..., and you also have to worry about SET DATEFIRST. I am also assuming “weekday” means “Mon, Tue, Wed, Thu, Fri”, and excluding Saturday and Sunday. (Or does TFIG apply across the globe?)
Thus, walking through my methodology, we start with what you had:
DECLARE
#Date datetime
,#BOM datetime
--SET #Date = '1/4/14' -- Should return Jan 31, 2013
SET #Date = '5/4/14' -- Should return May 30, 2014 (not May 31)
SET #BOM = DATEADD(m, DATEDIFF(m, 0, #date) + 1, 0)
PRINT #BOM
This sets #BOM (beginning of month) to the first day of the month after whatever you have in #Date. (I split this across multiple statements, because otherwise you have to repeat the function all over the place in the code below.)
Next, you have to “move back” from this day by one, two, or three days. If BOM is Monday, -3 to get to the prior Friday; if BOM is Sunday, -2 to get to Friday; otherwise, -1 will land you on a weekday. Based on the values returned by datepart, there’s no wifty algorithm I can think of to generate that -1/-2/-3 spread, so I use a case statement (I reject looping routines out of hand—far too kludgy for database work).
PRINT datepart(dw, #BOM) -- To see what is is
PRINT dateadd(dd, case
when datepart(dw, #BOM) = 2 then -3
when datepart(dw, #BOM) = 1 then -2
else -1
end
,#BOM)
Alas, this only works if your SQL instance is configured with the default “first day of week” setting; this is checked via PRINT ##datefirst, where 7 (the default) = Sun, 6 = Sat, and so forth. Once again, no wifty algorithm suggests itself, and the case statement turns into a mess:
PRINT dateadd(dd, case
when ##datefirst = 7 and datepart(dw, #BOM) = 2 then -3
when ##datefirst = 7 and datepart(dw, #BOM) = 1 then -2
when ##datefirst = 6 and datepart(dw, #BOM) = 3 then -3
when ##datefirst = 6 and datepart(dw, #BOM) = 2 then -2
when ##datefirst = 5 and datepart(dw, #BOM) = 4 then -3
when ##datefirst = 5 and datepart(dw, #BOM) = 3 then -2
when ##datefirst = 4 and datepart(dw, #BOM) = 5 then -3
when ##datefirst = 4 and datepart(dw, #BOM) = 4 then -2
when ##datefirst = 3 and datepart(dw, #BOM) = 6 then -3
when ##datefirst = 3 and datepart(dw, #BOM) = 5 then -2
when ##datefirst = 2 and datepart(dw, #BOM) = 7 then -3
when ##datefirst = 2 and datepart(dw, #BOM) = 6 then -2
when ##datefirst = 1 and datepart(dw, #BOM) = 1 then -3
when ##datefirst = 1 and datepart(dw, #BOM) = 7 then -2
else -1
end
,#BOM)
Ugly, or what? And looping structures have to account for this as well. Of course, if you can rely on always having the same language on your SQL Instances, it’s that much simpler:
PRINT dateadd(dd, case
when datename(dw, #BOM) = 'Monday' then -3
when datename(dw, #BOM) = 'Sunday' then -2
else -1
end
,#BOM)
Any or all of the above can and should be “concatenated down” into a single statement or query (or, better, a function); if you can safely make assumptions about your installation’s language and/or first day of week, you can shorten it even more.
you can try using the week day function like
select datename(dw, getdate())
and then from there use that in your query to derive the last week day in the month
so you could end up with something like this without actually having to create a "dates" table
declare #date datetime
set #date='3/4/13'
select case when datename(dw, DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, #date) + 1, 0))) = 'Saturday'
then DATEADD(d, -2, DATEADD(m, DATEDIFF(m, 0, #date) + 1, 0))
when datename(dw, DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, #date) + 1, 0))) = 'Sunday'
then DATEADD(d, -3, DATEADD(m, DATEDIFF(m, 0, #date) + 1, 0))
else DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, #date) + 1, 0))
end
, case when datename(dw, DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, #date) + 1, 0))) = 'Saturday'
then datename(dw, DATEADD(d, -2, DATEADD(m, DATEDIFF(m, 0, #date) + 1, 0)))
when datename(dw, DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, #date) + 1, 0))) = 'Sunday'
then datename(dw, DATEADD(d, -3, DATEADD(m, DATEDIFF(m, 0, #date) + 1, 0)))
else datename(dw, DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, #date) + 1, 0)))
end
declare #date datetime ='1/4/19'
select datename(dw, DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, #date) + 1, 0)))
This will give you the day name of the last day of the month.
select case when datename(dw,(EOMONTH(getdate()))) ='Saturday' then day(EOMONTH(getdate())) -1
when datename(dw,(EOMONTH(getdate()))) ='Sunday' then day(EOMONTH(getdate())) -2
else day(EOMONTH(getdate())) end
I wanted to get the week from the given date, for this I tried with the DATENAME function to get the WEEK like,
Select DateName(WEEK,'2012-03-09')
am getting the output as 10. I want to get the starting date and ending date of this week like, 2012-03-04 to 2012-03-10 Is it possible?
Do something like this:
DECLARE #MyDate Date = '2012-03-09';
-- This gets you the SUNDAY of the week your date falls in...
SELECT DATEADD(DAY, -(DATEPART(WEEKDAY, #MyDate) - 1), #MyDate);
-- This gets you the SATURDAY of the week your date falls in...
SELECT DATEADD(DAY, (7 - DATEPART(WEEKDAY, #MyDate)), #MyDate);
-- This will show the range as a single column
SELECT
CONVERT(NVarChar, DATEADD(DAY, -(DATEPART(WEEKDAY, #MyDate) - 1), #MyDate))
+ ' through ' +
CONVERT(NVarChar, DATEADD(DAY, (7 - DATEPART(WEEKDAY, #MyDate)), #MyDate));
try the following, change getdate to your date
Select
DateAdd(d, 1- DatePart(dw,GetDate()),GetDate()) FirstDayOfWeek,
DateAdd(d, 7- DatePart(dw,GetDate()),GetDate()) LastDayOfWeek
This does not rely on your default setting of datefirst.
set datefirst 4 -- this row does nothing in this query.
-- It will hurt the queries using datepart though
declare #t table(dt datetime)
insert #t values('2012-03-09 11:12'), ('2012-03-10 11:12'),('2012-03-11 11:12')
-- week from sunday to saturday
Select dateadd(week, datediff(week, 0, dt),-1),
dateadd(week, datediff(week, 0, dt),+5)
from #t
I may be using the wrong term (hence why I can't find it on google).
"Are there any functions or common code for Accounting Months Deliminations?"
For Example, this month started on a friday but on most accounting journals the weeks are measured by the first monday of the month so instead of having the 1st of July it would be the 4th of July. Same thing with the month end (29th instead of the 31st)
Again, I'm sure someone has created this 'wheel' before, and I can't seem to find it for the life of me.
The following query assumes a table, SalesTable, has a field called Amount (the value you want to sum) and a field called SaleDate (the date on which the sale occured.) It also assumes that accounting months begin the first Monday of the month and end on the Sunday prior to the beginning of the next accounting month.
Again, I highly recommend a table-based approach to this, but if you can't modify the schema, this should do the trick in T-SQL:
SELECT
CASE WHEN s.SaleDate < DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, s.SaleDate ),s.SaleDate )), 0)
THEN DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, DATEADD(day,-7,s.SaleDate) ),DATEADD(day,-7,s.SaleDate) )), 0)
ELSE DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, s.SaleDate ),s.SaleDate )), 0)
END AccountingMonth,
SUM(s.Amount) TotalSales
FROM SalesTable s
GROUP BY
CASE WHEN s.SaleDate < DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, s.SaleDate ),s.SaleDate )), 0)
THEN DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, DATEADD(day,-7,s.SaleDate) ),DATEADD(day,-7,s.SaleDate) )), 0)
ELSE DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, s.SaleDate ),s.SaleDate )), 0)
END
Note that the AccountingMonth return field actually contains the date of the first Monday of the month. In actual practice, you probably want to wrap this entire query in another query that reformats AccountingMonth to whatever you like... "2011-07", "2011-08", etc.
Here's how it works: This bit of code is the important part:
DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, s.SaleDate ),s.SaleDate )), 0)
It takes any date and returns the first Monday of the month in which that date occurred. In your case, however, you have to do a little more work because a sale might have occurred in the window between the first of the month and the first Monday of the month. The CASE statement detects that scenario and, if it's true, subtracts a week off of the date before calculating the first Monday.
Good luck!
-Michael
I have some code that takes in a year and month and returns the fiscal start and end dates. Perhaps this will give you something to go by:
DECLARE #yr int;
DECLARE #mo int;
SELECT #yr = 2011
SELECT #mo = 7
DECLARE #FiscalMonthStartDate datetime
DECLARE #FiscalMonthEndDate datetime
DECLARE #startOfMonth datetime
DECLARE #startOfNextMonth datetime
select #startOfMonth = CAST((CAST(#yr AS VARCHAR(4)) + '-' + CAST(#mo AS VARCHAR(2)) + '-' + '01') as DATE)
select #startOfNextMonth = CAST((CAST(#yr AS VARCHAR(4)) + '-' + CAST((#mo + 1) AS VARCHAR(2)) + '-' + '01') as DATE)
SELECT #FiscalMonthStartDate =
CASE
WHEN DATEPART(DW,#startOfMonth) = 0
THEN DATEADD(DD, 1, #startOfMonth)
ELSE
DATEADD(DD, 8 - DATEPART(DW,#startOfMonth), #startOfMonth)
END
SELECT #FiscalMonthEndDate =
CASE
WHEN DATEPART(DW,#startOfNextMonth) = 0
THEN DATEADD(DD, 1, #startOfNextMonth)
ELSE
DATEADD(DD, 8 - DATEPART(DW,#startOfNextMonth), #startOfNextMonth)
END
-- subtract one day to get end of fiscal month (not start of next fiscal month)
SELECT #FiscalMonthEndDate = DATEADD(DD, -1, #FiscalMonthEndDate)
SELECT #FiscalMonthStartDate, #FiscalMonthEndDate
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)