Select the first weekday of the next Month - sql

I am trying to modify someone else's code I found here to find the first weekday of next month (Link):
SELECT CASE
WHEN DATENAME(WEEKDAY, dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)) = 'Saturday'
THEN dateadd(mm, DATEDIFF(MM, 0, getdate()), 0) + 2
WHEN DATENAME(WEEKDAY, dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)) = 'Sunday'
THEN dateadd(mm, DATEDIFF(MM, 0, getdate()), 0) + 1
ELSE dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)
END
Here is what I have come up with (which doesn't work):
select CASE
WHEN DATENAME(WEEKDAY, eomonth(dateadd(mm, DATEDIFF(MM, 0, getdate()),1), 0 )) = 'Saturday'
THEN eomonth(dateadd(mm, DATEDIFF(MM, 0, getdate()), 0),1) + 2
WHEN DATENAME(WEEKDAY, eomonth(dateadd(mm, DATEDIFF(MM, 0, getdate()),1), 0)) = 'Sunday'
THEN eomonth(dateadd(mm, DATEDIFF(MM, 0, getdate()), 0),1) + 1
ELSE eomonth(dateadd(mm, DATEDIFF(MM, 0, getdate()), 1),1)
end
Thanks for the help!

Your query implementation looks like for SQL server. You may use DATEFROMPARTS or EOMONTH function to get first day of next month, then use DATENAME in CASE expression to decide the first weekday like below (SQL Server only).
-- get first day of next month using DATEFROMPARTS
Declare #NextMonthFirstDate datetime = DATEFROMPARTS(YEAR(GETDATE()),MONTH(GETDATE())+1,1)
-- then use CASE expression
Select CASE WHEN DATENAME(WEEKDAY, #NextMonthFirstDate) = 'Sunday'
THEN #NextMonthFirstDate + 1
WHEN DATENAME(WEEKDAY, #NextMonthFirstDate) = 'Saturday'
THEN #NextMonthFirstDate + 2
ELSE #NextMonthFirstDate END as FirstWeekDayOfnextMonth

Related

Subtracting one month from a date but making sure it is the first business day of that month

I need to subtract one month from a date called ArchiveDate but I want the first business day of that month. For example if my ArchiveDate is 9/2/2018 I would like to have 8/1/2019.
This is what I have:
DECLARE #ArchiveDate date = '9/2/2019'
SELECT ArchiveDate = DATEADD(day,
CASE WHEN
DATEPART(weekday, DATEADD(MONTH, -1, #ArchiveDate)) = 1
THEN 1
WHEN DATEPART(weekday, DATEADD(MONTH, -1, #ArchiveDate)) = 7 THEN 2
ELSE 0
END
, DATEADD(MONTH, -1, #ArchiveDate))
What I get from this is 8/2/2019 but as you can see I want 8/1/2019.
SELECT
CASE
WHEN DATENAME(WEEKDAY, DATEADD(mm, DATEDIFF(mm, 0, #ArchiveDate) - 1, 0)) = 'Saturday'
THEN DATEADD(mm, DATEDIFF(mm, 0, #ArchiveDate) - 1, 0) + 2
WHEN DATENAME(WEEKDAY, DATEADD(mm, DATEDIFF(mm, 0, #ArchiveDate) - 1, 0)) = 'Sunday'
THEN DATEADD(mm, DATEDIFF(mm, 0, #ArchiveDate) - 1, 0) + 1
ELSE
DATEADD(mm, DATEDIFF(mm, 0, #ArchiveDate) - 1, 0)
END
This will return the first BUSINESS DAY of the previous month.
you can use eomonth along with your logic to get first day of previous month as below:
DECLARE #ArchiveDate date = '9/2/2019'
select dateadd(day, 1, eomonth(dateadd(month, -2, #ArchiveDate)));
You can use EOMONTH with DATEADD():
SELECT DATEADD(DAY, 1, EOMONTH(#ArchiveDate, -2)) AS ArchiveDate

How to return just the yyyy-mm-dd from the following SQL queries [duplicate]

This question already has answers here:
How to get a date in YYYY-MM-DD format from a TSQL datetime field?
(25 answers)
Closed 4 years ago.
Below are the queries I created. Query #1 returns 2018-07-06 00:00:00.000 and query #2 returns 2018-07-31 23:59:59.997.
I can't figure out how to modify the queries so that they'll return the result in the yyyy-mm-dd format. Please advice.
Query #1 - get fifth business day of the month
SELECT
FifthWeekDay = DATEADD(dd, CASE
WHEN DATEDIFF(dd, -1, ca.FirstOfMonth) % 7 > 1 -- -1 is a Sunday
THEN 7
ELSE 6 - DATEDIFF(dd, -1, ca.FirstOfMonth) % 7 -- -1 is a Sunday
END, ca.FirstOfMonth - 1)
FROM
(SELECT
DATEADD(mm, (SELECT DATEPART(YEAR, GETDATE())) * 12 - 22801 +
(SELECT DATEPART(M, GETDATE())), 0)) ca(FirstOfMonth)
Query #2 - get last business day of the month
SELECT
DATEADD(ms, -3, DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) + 1, 0))
- CASE DATENAME(dw, DATEADD(ms, -3, DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) + 1, 0)))
WHEN 'SUNDAY' THEN 2
WHEN 'SATURDAY' THEN 1
ELSE 0
END AS LastBusinessCurrentMonth
You can subquery the results you already have and add a cast( as date):
SELECT CAST(LastBusinessCurrentMonth AS DATE) AS LastBusinessCurrentMonth FROM(
SELECT
DATEADD(ms, -3, DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) + 1, 0))
- CASE DATENAME(dw, DATEADD(ms, -3, DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) + 1, 0)))
WHEN 'SUNDAY' THEN 2
WHEN 'SATURDAY' THEN 1
ELSE 0
END AS LastBusinessCurrentMonth) AS X
SELECT CAST(FIFTHWEEKDAY AS DATE) AS FIFTHWEEKDAY FROM(
SELECT
FifthWeekDay = DATEADD(dd, CASE
WHEN DATEDIFF(dd, -1, ca.FirstOfMonth) % 7 > 1 -- -1 is a Sunday
THEN 7
ELSE 6 - DATEDIFF(dd, -1, ca.FirstOfMonth) % 7 -- -1 is a Sunday
END, ca.FirstOfMonth - 1)
FROM
(SELECT
DATEADD(mm, (SELECT DATEPART(YEAR, GETDATE())) * 12 - 22801 +
(SELECT DATEPART(M, GETDATE())), 0)) ca(FirstOfMonth)) AS X
Or you could declare a variable as Date and set the results of your queries to that variable :
DECLARE #DATEVAR DATE
SET #DATEVAR =(
SELECT
DATEADD(ms, -3, DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) + 1, 0))
- CASE DATENAME(dw, DATEADD(ms, -3, DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) + 1, 0)))
WHEN 'SUNDAY' THEN 2
WHEN 'SATURDAY' THEN 1
ELSE 0
END AS LastBusinessCurrentMonth)
SELECT #DATEVAR AS LastBusinessCurrentMonth
SET #DATEVAR = (SELECT
DATEADD(ms, -3, DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) + 1, 0))
- CASE DATENAME(dw, DATEADD(ms, -3, DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) + 1, 0)))
WHEN 'SUNDAY' THEN 2
WHEN 'SATURDAY' THEN 1
ELSE 0
END AS LastBusinessCurrentMonth)
SELECT #DATEVAR AS LastBusinessCurrentMonth

Explain This Query

Could anyone explain this query?
SELECT CASE
WHEN DATENAME(WEEKDAY, dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)) = 'Saturday'
THEN
REPLACE('RXRatingsTrialV3DailyChange' + CONVERT(VARCHAR(10), DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0)+2,111),'/','')
WHEN DATENAME(WEEKDAY, dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)) = 'Sunday'
THEN
REPLACE('RXRatingsTrialV3DailyChange' + CONVERT(VARCHAR(10), DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0)+1,111),'/','')
ELSE
REPLACE('RXRatingsTrialV3DailyChange' + CONVERT(VARCHAR(10), DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0),111),'/','')
END
AS RXRatingsTrialV3DailyChange
The result is RXRatingsTrialV3DailyChange20150501. What I really do not understand is what part of the query is writing the date, '20150501'?
Thanks
The DATEADD with the ,0) is doing this.
SELECT CASE
WHEN DATENAME(WEEKDAY, dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)) = 'Saturday'
THEN
REPLACE('RXRatingsTrialV3DailyChange' + CONVERT(VARCHAR(10), DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0)+2,111),'/','')
WHEN DATENAME(WEEKDAY, dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)) = 'Sunday'
THEN
REPLACE('RXRatingsTrialV3DailyChange' + CONVERT(VARCHAR(10), DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0)+1,111),'/','')
ELSE
REPLACE('RXRatingsTrialV3DailyChange' + CONVERT(VARCHAR(10), DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0),111),'/','')
END
AS RXRatingsTrialV3DailyChange,
getdate()m,
DATEDIFF(mm,0,GETDATE()),
DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0)

First business day of the current month - SQL Server

How could I get the first business day of the current month?
Without create a function, only select.
something like that:
SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(GETDATE())-1), GETDATE()), 101)
somebody knows please?
Thanks.
A Simple case statement could do it
SELECT CASE
WHEN DATENAME(WEEKDAY, dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)) = 'Saturday'
THEN dateadd(mm, DATEDIFF(MM, 0, getdate()), 0) + 2
WHEN DATENAME(WEEKDAY, dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)) = 'Sunday'
THEN dateadd(mm, DATEDIFF(MM, 0, getdate()), 0) + 1
ELSE dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)
END
This will literally give you what you're asking for -- the first business day in a month if we define a business day as "any day that's not a Saturday or a Sunday". But this is is a very narrow definition of "business day" that is not appropriate when taking into account holidays and cultural differences, so it generalizes poorly. The typical solution for this problem is to create a table that actually holds the working days (which is generated somewhere just before he year, or calculated in advance if that's feasible), and simply look it up in that.
SELECT DATEADD(DAY,
CASE
(DATEPART(WEEKDAY, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)) + ##DATEFIRST - 1) % 7
WHEN 6 THEN 2
WHEN 7 THEN 1
ELSE 0
END,
DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)
)
This solution uses ##DATEFIRST to avoid any language issues -- using DATEPART(WEEKDAY, ...) on its own or DATENAME() only works if we assume a specific region.
If you have more flexibility in your SELECT statement, you might be able to use something like this:
;With Daterange As
(
Select DateAdd(Month, DateDiff(Month, 0, GetDate()), 0) As Date Union All
Select DateAdd(Day, 1, Date) As Date
From DateRange
Where Date < DateAdd(Day, 6, DateAdd(Month, DateDiff(Month, 0, GetDate()), 0))
)
Select Convert(Date, Min(Date)) FirstBusinessDay
From Daterange
Where DatePart(WeekDay, Date) Not In (7, 1)
Try this.
SELECT CASE
WHEN Datename(dw, Dateadd(dd, -Datepart(dd, Getdate()) + 1, Getdate())) = 'Saturday' THEN Dateadd(dd, -Datepart(dd, Getdate()) + 3, Getdate())
WHEN Datename(dw, Dateadd(dd, -Datepart(dd, Getdate()) + 1, Getdate())) = 'Sunday' THEN Dateadd(dd, -Datepart(dd, Getdate()) + 2, Getdate())
ELSE Dateadd(dd, -Datepart(dd, Getdate()) + 1, Getdate())
END
Explanation :
Find the first day of the month.
Dateadd(dd, -Datepart(dd, Getdate()) + 1, Getdate())
Then check the day of the previous date by using Datename function.
Datename(dw, Dateadd(dd, -Datepart(dd, Getdate()) + 1, Getdate()))
If the Datename is Saturday the add 2 days to the first day of the month . if it is sunday then add 1 day to the first day of the month else get the first day of the month

GETDATE last month

I am trying to list last a website's statistics.
I listed Last 30 days with;
CONVERT(VARCHAR(10), S.DATEENTERED, 101)
BETWEEN
CONVERT(VARCHAR(10), GETDATE()-30, 101)
AND
CONVERT(VARCHAR(10), GETDATE(), 101)
and this month with;
RIGHT(CONVERT(VARCHAR(10), S.DATEENTERED, 103), 7) =
RIGHT(CONVERT(VARCHAR(10), GETDATE(), 103), 7)
but I have no idea what query to use for last month. I tried with;
RIGHT(CONVERT(VARCHAR(10), S.DATEENTERED, 103), 7) =
RIGHT(CONVERT(VARCHAR(10), GETDATE()-1, 103), 7)
Did not work.
Dates are always a joy to work with in any programming language, SQL not excluded.
To answer your question to find all records that occurred last month
select S.DATEENTERED
,*
from sometable S
where S.DATEENTERED
between dateadd(mm, datediff(mm, 0, dateadd(MM, -1, getdate())), 0)
and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(MM, -1, getdate())) + 1, 0))
order by 1
To expand the best means for getting records within a certain time-frame is by utilizing the datediff function, dateadd function, and the between condition in the where clause.
select 'howdy'
,getdate()
where getdate()
between dateadd(mm, 0, 0)
and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(mm,-1,getutcdate())) + 1, 0))
The above code will result in no records returned because it is checking to see if today's date is between 1900-01-01 00:00:00.000 and the last possible recorded date of last month (the last day and 23:59:59.997 - SQL Server DATETIME columns have at most a 3 millisecond resolution).
The following code will return a record as the date we are searching for is one month ago.
select 'howdy'
,dateadd(mm, -1, getdate())
where dateadd(mm, -1, getdate())
between dateadd(mm, 0, 0)
and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(mm,-1,getutcdate())) + 1, 0))
A break down of the where clause:
WHERE getdate() -- date to check
between dateadd(mm, 0, 0) -- begin date
and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(mm,-1,getutcdate())) + 1, 0)) -- end date
Finally, a variety of dates can be ascertained in this manner here is a pretty complete list:
select dateadd(mm, 0, 0) as BeginningOfTime
,dateadd(dd, datediff(dd, 0, getdate()), 0) as Today
,dateadd(wk, datediff(wk, 0, getdate()), 0) as ThisWeekStart
,dateadd(mm, datediff(mm, 0, getdate()), 0) as ThisMonthStart
,dateadd(qq, datediff(qq, 0, getdate()), 0) as ThisQuarterStart
,dateadd(yy, datediff(yy, 0, getdate()), 0) as ThisYearStart
,dateadd(dd, datediff(dd, 0, getdate()) + 1, 0) as Tomorrow
,dateadd(wk, datediff(wk, 0, getdate()) + 1, 0) as NextWeekStart
,dateadd(mm, datediff(mm, 0, getdate()) + 1, 0) as NextMonthStart
,dateadd(qq, datediff(qq, 0, getdate()) + 1, 0) as NextQuarterStart
,dateadd(yy, datediff(yy, 0, getdate()) + 1, 0) as NextYearStart
,dateadd(ms, -3, dateadd(dd, datediff(dd, 0, getdate()) + 1, 0)) as TodayEnd
,dateadd(ms, -3, dateadd(wk, datediff(wk, 0, getdate()) + 1, 0)) as ThisWeekEnd
,dateadd(ms, -3, dateadd(mm, datediff(mm, 0, getdate()) + 1, 0)) as ThisMonthEnd
,dateadd(ms, -3, dateadd(qq, datediff(qq, 0, getdate()) + 1, 0)) as ThisQuarterEnd
,dateadd(ms, -3, dateadd(yy, datediff(yy, 0, getdate()) + 1, 0)) as ThisYearEnd
Using the above list a range of any type can be determined.
The following will find you the start of the last month:
-- Start of last month
SELECT CAST('01 '+ RIGHT(CONVERT(CHAR(11),DATEADD(MONTH,-1,GETDATE()),113),8) AS datetime)
You would then find the start of this month, using the following, minus one.
-- Start of the month
SELECT CAST('01 '+ RIGHT(CONVERT(CHAR(11),GETDATE(),113),8) AS datetime)
When I have to work with dates in SQL Server I often reference Robyn Page's SQL Server DATE/TIME Workbench. The workbench (tutorial) is well laid out and contains just about everything I have ever needed when working with dates on SQL Server.
How about this?
select DATEADD(month, -1, GETDATE())
I would suggest using the first day of last month and the first day of the current month for the operation and rather than using BETWEEN use >= and <. That's my personal opinion, but I believe you will find there are performance and maintainability benefits to this approach.
Here's the sql. You will notice I've included the last day of the last month value just in case you end up going with another approach.
Keep in mind, these dates are based off of 12:00AM that day. In other words, getting values between 6/1/2009 and 6/30/2009 won't get you what you want as all of 6/30/2009 is excluded. If you use the first day of July (7/1/2009) you are covered.
Again, I recommend avoiding BETWEEN all together as shown below. Best of luck.
Declare #LastMonthFirstDay datetime
Declare #LastMonthLastDay datetime
Declare #ThisMonthFirstDay datetime
Set #LastMonthFirstDay = DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP) - 1, 0);
Set #ThisMonthFirstDay = DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0);
Set #LastMonthLastDay = DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0));
Select * From Table
Where DateEntered >= #LastMonthFirstDay
And DateEntered < #ThisMonthFirstDay;
Try using the DATEADD function. You can add a -1 with the MONTH (mm) datepart and it should work. Here is a link
where year(S.DATEENTERED) = year(dateadd(mm, -1, getdate())) and month(S.DATEENTERED) = month(dateadd(mm, -1, getdate()))
Might not be good performance-wise but you've got the idea.
GET FIRST DAY OF LAST MONTH
SELECT DATEADD(MM, DATEDIFF(MM, '01/01/2000', DATEADD(MM, -1,GETDATE())), '01/01/2000')
GET LAST DAY OF LAST MONTH
SELECT DATEADD(SS,-1,DATEADD(MM, DATEDIFF(MM,'01/01/2000',GETDATE()),'01/01/2000'))
Then search based on this range.
Try:
declare #lastm int
set #lastm = datepart(mm,getdate()) - 1
...
where datepart(mm,s.dateentered) = #lastm