Create custom quarters with start and end date from given date - sql

Suppose My Date is = 2023-03-28 I want to create quarters as shown in below table.
Q1-StartDate
Q1-EndDate
Q2-StartDate
Q2-EndDate
Q3-StartDate
Q3-EndDate
Q4-StartDate
Q4-EndDate
2023-03-01
2023-05-31
2023-06-01
2023-08-31
2023-09-01
2023-11-30
2023-12-01
2024-02-29
I Want to take care of leap year as well, that's why I used example with leap year that is for ex. Q4-end date is 29.
My date can be random. How can I do this in SQL using a function, a stored procedure, or anything like that?

Find the Q1 start date by subtracting the day of date and adding 1 day.
Rest all quarter start date can be determined by just adding 1 day to the previous quarter end date.
End date of all quarters can be determined by adding 3 months to the start date of the specific quarter and adding 1 day.
Query
declare #dt as date;
set #dt = '2023-03-28';
declare #q1_start as date,
#q1_end as date,
#q2_start as date,
#q2_end as date,
#q3_start as date,
#q3_end as date,
#q4_start as date,
#q4_end as date;
set #q1_start = dateadd(day, -day(#dt) + 1, #dt);
set #q1_end = dateadd(day, -1, dateadd(month, 3, #q1_start));
set #q2_start = dateadd(day, 1, #q1_end);
set #q2_end = dateadd(day, -1, dateadd(month, 3, #q2_start));
set #q3_start = dateadd(day, 1, #q2_end);
set #q3_end = dateadd(day, -1, dateadd(month, 3, #q3_start));
set #q4_start = dateadd(day, 1, #q3_end);
set #q4_end = dateadd(day, -1, dateadd(month, 3, #q4_start));
select #q1_start as Q1_Start,
#q1_end as Q1_End,
#q2_start as Q2_Start,
#q2_end as Q2_End,
#q3_start as Q3_Start,
#q3_end as Q3_End,
#q4_start as Q4_Start,
#q4_end as Q4_End;

You may use EOMONTH and DATEADD functions as the following:
DECLARE #sdate Date;
SET #sdate = '2023-03-28';
SELECT
DATEADD(DAY,1,EOMONTH(#sdate,-1)) [Q1-StartDate], EOMONTH(#sdate,2) [Q1-EndDate],
DATEADD(DAY,1,EOMONTH(#sdate,2)) [Q2-StartDate], EOMONTH(#sdate,5) [Q2-EndDate],
DATEADD(DAY,1,EOMONTH(#sdate,5)) [Q3-StartDate], EOMONTH(#sdate,8) [Q3-EndDate],
DATEADD(DAY,1,EOMONTH(#sdate,8)) [Q4-StartDate], EOMONTH(#sdate,11) [Q4-EndDate]
See demo

Related

Pulling Previous week based upon getdate

I am looking to sum last weeks sales based upon the getdate. I need to look at today's date and which is in week 24 and sum all sales for week 23 which is the previous week. I am looking to do this dynamically based upon the getdate()
Below query will help you
DECLARE #CurrentDate datetime,
#CurrentWeekFrom datetime,
#LastWeekFrom datetime,
#LastWeekEnd datetime
SET #CurrentDate = GetDate()
SET #CurrentWeekFrom = DateAdd(wk, DateDiff(wk, 0, #CurrentDate), 0)
SET #LastWeekFrom = DateAdd(wk, -1, #CurrentWeekFrom)
SET #LastWeekEnd = DateAdd(dd, -1, #LastWeekFrom)
SELECT SUM(Sales) AS Sales FROM table1
Where SalesDate Between #LastWeekFrom And #LastWeekEnd

How to query 2 different date ranges depending on the day it is run

I am making a program that auto-runs using windows scheduler. What I'd like to do is set the program to run on the 1st and the 16th of every month. If the program run's on the 1st. I'd like to have the query run for last month... For example if today was the first of august I would want it to run 7/1/12 - 7/31/12. If I run the program on the 16th I want it to run the query for the current month to the 15th. For example if it were 8/16, I would want the program to run the query for 8/1/12 - 8/15/12. What is the best way to accomplish this? Do I go with 2 seperate programs with the query attaching it to the correct date range? One scheduled to run on the first of every month, and one on the 16th? How would I go about getting the date range and the year as it will depend on which month/year it is run... My query is:
SELECT Store_Number, Invoice_Number, Invoice_Date, Extended_Price, Warranty_Amount, Quantity_Sold, Invoice_Detail_Code
FROM Invoice_Detail_Tb
WHERE (Warranty_Amount > 0) AND (Invoice_Date BETWEEN CONVERT(DATETIME, '2012-08-01 00:00:00', 102) AND CONVERT(DATETIME, '2012-08-05 00:00:00', 102))
ORDER BY Store_Number, Invoice_Date
Try 8/1/2012 and 8/16/2012 as the date. It returns the values you want to see:
declare #date datetime = '8/16/2012', #start datetime, #end datetime
if datepart(dd, #date) = 1
begin
set #start = dateadd(mm, -1, #date)
set #end = dateadd(dd, -1, #date)
end
else
begin
set #start = dateadd(dd, -15, #date)
set #end = dateadd(dd, -1, #date)
end
select #start, #end
It would be fairly easy to adapt this so that it would dynamically calculate the correct start and end dates based on any input date -- so you could run it anytime during the month.
This should be simple, let me throw some examples for you.
I truly think this should be one scheduled task, not multiple ones.
It is easier at the end of the day to point and look at one scheduled task (one procedure)
then go digging up multiple procedures just to see what might have wen't wrong.
The task can be scheduled using the SQL Server Agent (under the jobs section). The job can point to one single stored procedure.
In the procedure you can do a simple if else if logic.
IF DAY(GetDate()) = 1
--code here
ELSE IF DAY(GETDATE()) = 16
--code here
DAY(date_expression) returns the day in a datetime column. Ironically there is a MONTH and YEAR function if you for some reason need those. The rest is simple, if you are on the first date of the month then perform the monthly query from months first date till next months first day - 1, this becomes:
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
Otherwise if it hits on the 16th, you can run on the first day until half of the month.
If you have your query in a view, you might use this:
where
Invoice_Date between
(
case
when datepart(dd, getdate()) = 1 then dateadd(mm, -1, getdate())
else dateadd(dd, -15, getdate())
end
)
and
(
case
when datepart(dd, getdate()) = 1 then dateadd(dd, -1, getdate())
else dateadd(dd, -1, getdate())
end
)
UPDATE: Ignoring the time
(I know it looks ugly.)
where
Invoice_Date between
(
case
when datepart(dd, dateadd(dd, datediff(dd, 0, getdate()), 0)) = 1 then dateadd(mm, -1, dateadd(dd, datediff(dd, 0, getdate()), 0))
else dateadd(dd, -15, dateadd(dd, datediff(dd, 0, getdate()), 0))
end
)
and
(
case
when datepart(dd, dateadd(dd, datediff(dd, 0, getdate()), 0)) = 1 then dateadd(dd, -1, dateadd(dd, datediff(dd, 0, getdate()), 0))
else dateadd(dd, -1, dateadd(dd, datediff(dd, 0, getdate()), 0))
end
)
This is how I usually do something like that. Your stored procedure should look something like this:
declare
#today datetime ,
#dtFrom datetime ,
#dtThru datetime
------------------------------------------------------
-- get the current date, discarding the time component
------------------------------------------------------
set #today = convert(datetime,convert(varchar,current_timestamp,112),112) -- get todays date, discarding the time component
---------------------------------------------------------------------------------------------------------------------------------------------------
-- determine the start/end dates of the query period.
--
-- if the query date (#today) is in the 1st half of the month (1st - 15th), the query range is the entire preceding month
-- if the query date (#today) is in the last half of the month (16 - 31st), the query range is the 1st of the current month up to the current date
---------------------------------------------------------------------------------------------------------------------------------------------------
if ( datepart(day) < 16 )
begin
set #dtThru = dateadd(day, - datepart(day, #today ) , #today ) -- set the end date to the last day of the previous month
set #dtFrom = dateadd(day, 1 - datepart(day, #dtThru ) , #dtThru ) -- set the start date to the first day of the previous month
end
else
begin
set #dtfrom = dateadd(day, 1 - datepart(day, #today) , #today ) -- set the start date to the first day of the current month
set #dtThru = #today
end
----------------------------------------------------------------------------------------------------------------------
-- finally, adjust the start/end times to cover the entire gamut of date/time values for the month
--
-- We don't have to modify #dtFrom at all: we know its time component is 00:00:00.000 already. However, we want
-- #dtThru to have a time component of 23:59:59.997, due to SQL Server's broken way of counting time -- any time value
-- higher than that (e.g., '23:59.59.999') is 'rounded up' to start-of-day (00:00.00.000), the next day. Brilliant!
--
----------------------------------------------------------------------------------------------------------------------
set #dtThru = dateadd(ms, -3 , dateadd(day,1,#dtThru) )
--------------------------------
-- return the data to the caller
--------------------------------
SELECT Store_Number ,
Invoice_Number ,
Invoice_Date ,
Extended_Price ,
Warranty_Amount ,
Quantity_Sold ,
Invoice_Detail_Code
FROM Invoice_Detail_Tb id
WHERE Warranty_Amount > 0
AND Invoice_Date BETWEEN #dtFrom AND #dtThru
ORDER BY Store_Number ,
Invoice_Date
If you aren't using a stored procedure, you can accomplish the same thing with a parameterized query. Compute the two DateTime values needed. Put placeholders in your select statement ('#dtFrom' and '#dtThru'). When you execute the query, pass in your two DateTime values as SqlParameter objects with names matching the placeholders.

SQL How to determine if date month date contains 29,30 or 31

This is what I am trying to do. I need to add one month to the transaction date so that the next month effective date
start on the same day as the starting effective date. If the starting Effective day is (30, 31) is not in the next month (eg. feb 28), then it should give (march 1st) as a next effective date. The transaction date is simply to know which month to use to add a month.
For example, the next Month effective date is showing fine as in this example
'2011-04-20'.
declare #StartEffectiveDate datetime
declare #transactiondate datetime
declare #NextMonthEffectivedate datetime
set #StartEffectiveDate = '2011-01-20'
set #transactiondate = '2011-03-14'
--calculating next month effective date. incremening transactiondate by 1, but on same day --as the starting effective date.
set #NextMonthEffectivedate = dateadd(month,month(#transactiondate)-month(#StartEffectiveDate)+1,#Starteffectivedate)
But,
if the #StartEffectiveDate is on '2011-01-31', #transactiondate = '2011-01-30', then the result for Next month effective date should be '2011-03-01' because 2011-02-31' is not a valid date.
How to check if next month date has the starting effective day or not. In this example, how to check if Feb has 31 or not. If it doesn't have 31, then it should show '2011-03-01'
Many thanks for your help!!!
After adding a month, compare DAY. If less because DATEADD goes to end of the month instead (eg 31 Jan to 28 Feb), then skip to next month
The DATEADD/DATEDIFF here skips to the start of the following month
declare #StartEffectiveDate datetime
set #StartEffectiveDate = '2011-01-20'
SELECT
CASE
WHEN DAY(#StartEffectiveDate) <= DAY(DATEADD (MONTH, 1, #StartEffectiveDate)) THEN DATEADD (MONTH, 1, #StartEffectiveDate)
ELSE DATEADD(day, 1, DATEADD (MONTH, 1, #StartEffectiveDate))
END
set #StartEffectiveDate = '2011-01-31'
SELECT
CASE
WHEN DAY(#StartEffectiveDate) <= DAY(DATEADD (MONTH, 1, #StartEffectiveDate)) THEN DATEADD (MONTH, 1, #StartEffectiveDate)
ELSE DATEADD(day, 1, DATEADD (MONTH, 1, #StartEffectiveDate))
END
set #StartEffectiveDate = '2011-02-28'
SELECT
CASE
WHEN DAY(#StartEffectiveDate) <= DAY(DATEADD (MONTH, 1, #StartEffectiveDate)) THEN DATEADD (MONTH, 1, #StartEffectiveDate)
ELSE DATEADD(day, 1, DATEADD (MONTH, 1, #StartEffectiveDate))
END
Edit: only need to add an extra day rather then some fancy DATEADD/DATEDIFF...
This should work:
declare #StartEffectiveDate datetime
declare #transactiondate datetime
declare #NextMonthEffectivedate datetime
set #StartEffectiveDate = '20110131'
set #transactiondate = '20110130'
--calculating next month effective date. incremening transactiondate by 1, but on same day --as the starting effective date.
set #NextMonthEffectivedate = dateadd(month,DATEDIFF(month,#StartEffectiveDate,#transactionDate)+1,#StartEffectiveDate)
if DATEPART(day,#StartEffectiveDate) <> DATEPART(day,#NextMonthEffectiveDate)
begin
--rounding occurred - next month isn't long enough.
set #NextMonthEffectivedate = DATEADD(day,1,#NextMonthEffectiveDate)
end
print #NextMonthEffectivedate
select datepart(day, getdate())
This gets you the day of the month. So here's the full script, though I didn't understand what you're doing with #StartEffectiveDate so I just kept that the same:
declare #StartEffectiveDate datetime
declare #transactiondate datetime
declare #NextMonthEffectivedate datetime
set #StartEffectiveDate = '2011-01-20'
set #transactiondate = '2011-03-30'
--calculating next month effective date. incremening transactiondate by 1, but on same day --as the starting effective date.
set #NextMonthEffectivedate =
case
when datepart(day, #transactiondate) > 28 then dateadd(month,2,dateadd(day,-1*(datepart(day, #transactiondate)-1),#transactiondate))
else dateadd(month,month(#transactiondate)-month(#StartEffectiveDate)+1,#Starteffectivedate)
end
select #NextMonthEffectivedate
Check last day of a month.
SELECT day(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0)))
Add 1 month in date.
SELECT DATEADD(month,13,getdate());
Check first day of the month
SELECT CAST(CAST(YEAR(GETDATE()) AS VARCHAR(4)) + '/' +
CAST(MONTH(GETDATE()) AS VARCHAR(2)) + '/01' AS DATETIME)
We can create a scalar function for this.
CREATE FUNCTION dbo.DaysInMonth(#date DATETIME) RETURNS int
AS
BEGIN
RETURN (SELECT DAY(DATEADD(m, 1, #date - DAY(#date))))
END
This SQL statement gives last date of a month, you just need to replace GETDATE() with your desired datetime variable or your column name.
DECLARE #lastDateOfMonth AS INT= DATEPART(DD, DATEADD(s, -1, DATEADD(mm, DATEDIFF(m, 0, GETDATE()) + 1, 0)));
SQL does not directly support this. You would need to create a function that checks for the correct days. See an example
Here

Get first Sunday of next month using T-SQL

Looking for a way to get the date in the format "11/1/2009", which would be the first sunday of next month. I want to run this query after the first sunday in october to get the first sunday of the upcoming month. What is the best method to accomplish this with a T-SQL query?
Thanks
try this:
Declare #D Datetime
Set #D = [Some date for which you want the following months' first sunday]
Select DateAdd(day, (8-DatePart(weekday,
DateAdd(Month, 1+DateDiff(Month, 0, #D), 0)))%7,
DateAdd(Month, 1+DateDiff(Month, 0, #D), 0))
EDIT Notes:
The first of next Month is given by the expression:
DateAdd(Month, 1+DateDiff(Month, 0, #D), 0)
or by:
which can be modified to give the first of the month two months from now by changing the 1 to a 2:
DateAdd(Month, 2+DateDiff(Month, 0, #D), 0)
EDIT: In response to #NissanFan, and #Anthony: to modify this to return the first Monday Tuesday Wednesday, etc, change the value 8 to a 9, 10, 11, etc....
Declare #Sun TinyInt Set #Sun = 8
Declare #Mon TinyInt Set #Mon = 9
Declare #Tue TinyInt Set #Tue = 10
Declare #Wed TinyInt Set #Wed = 11
Declare #Thu TinyInt Set #Thu = 12
Declare #Fri TinyInt Set #Fri = 13
Declare #Sat TinyInt Set #Sat = 14
Declare #D Datetime, #FONM DateTime -- FirstofNextMonth
Set #D = [Some date for which you want the following months' first sunday]
Set #FONM = DateAdd(Month, 1+DateDiff(Month, 0, #D),0)
Select
DateAdd(day, (#Sun -DatePart(weekday, #FONM))%7, #FONM) firstSunInNextMonth,
DateAdd(day, (#Mon -DatePart(weekday, #FONM))%7, #FONM) firstMonInNextMonth,
DateAdd(day, (#Tue -DatePart(weekday, #FONM))%7, #FONM) firstTueInNextMonth,
DateAdd(day, (#Wed -DatePart(weekday, #FONM))%7, #FONM) firstWedInNextMonth,
DateAdd(day, (#Thu -DatePart(weekday, #FONM))%7, #FONM) firstThuInNextMonth,
DateAdd(day, (#Fri -DatePart(weekday, #FONM))%7, #FONM) firstFriInNextMonth,
DateAdd(day, (#Sat -DatePart(weekday, #FONM))%7, #FONM) firstSatInNextMonth
Just an FYI rather then coming up with some code to do this how about using a calendar table.
Take a look at this: http://web.archive.org/web/20070611150639/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html
This also may help:
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=99696
Here is a query to get first working day of next month
DECLARE #DAYOFWEEK INT,#ReminderDate DateTime
SET #DAYOFWEEK = DATEPART( WEEKDAY,DateAdd(D,- Day(GetDate())+1, DATEADD(M,1,GetDate())) )
Print #DAYOFWEEK
If #DAYOFWEEK = 1
Set #ReminderDate = DateAdd(D,- Day(GetDate())+2, DATEADD(M,1,GetDate()))
Else If #DAYOFWEEK =7
Set #ReminderDate = DateAdd(D,- Day(GetDate())+3, DATEADD(M,1,GetDate()))
Else
Set #ReminderDate = DateAdd(D,- Day(GetDate())+1, DATEADD(M,1,GetDate()))
Print #ReminderDate
Reference taken from this blog:
SQL Server 2012 introduced one new TSQL EOMONTH to return the last day of the month that contains the specified date with an optional offset.
CREATE TABLE tbl_Test_EOMONTH
(
SampleDate DATETIME
)
GO
INSERT INTO tbl_Test_EOMONTH VALUES ('2015-12-20')
INSERT INTO tbl_Test_EOMONTH VALUES ('2015-11-08')
INSERT INTO tbl_Test_EOMONTH VALUES ('2015-10-16')
INSERT INTO tbl_Test_EOMONTH VALUES ('2015-09-26')
INSERT INTO tbl_Test_EOMONTH VALUES ('2016-01-31')
GO
SELECT
DATEADD(DAY,8-DATEPART(WEEKDAY,DATEADD(DAY,0,EOMONTH([SampleDate])))
,EOMONTH([SampleDate])) AS FirstSunday_ofTheNextMonth
FROM tbl_Test_EOMONTH
GO
You can use DATENAME to determine the day you want, I might recommend a loop to move the date from the 01 of the month in question to get to the first sunday.
So lets try:
DECLARE #DateTime DATETIME
Set to the date to start off with, then add 1 day until you find what you are looking for. Use datename with dw...
We have used this to determine weekends, but holidays will be a problem, where we use a table to store that.
Try this code as a function:
-- Variables
DECLARE #DATE DATETIME
DECLARE #DAY INT
DECLARE #DAYOFWEEK INT
DECLARE #TESTDATE DATETIME
-- Set
SET #TESTDATE = GETDATE()
SET #DATE = DATEADD( MONTH, 1, #TESTDATE )
SET #DAY = DATEPART( DAY, #TESTDATE )
SET #DATE = DATEADD( DAY, -#DAY + 1, #DATE )
SET #DAYOFWEEK = DATEPART( WEEKDAY, #DATE )
IF #DAYOFWEEK > 1
BEGIN
SET #DAYOFWEEK = 8 - #DAYOFWEEK
END
ELSE
BEGIN
SET #DAYOFWEEK = 0
END
SET #DATE = DATEADD( DAY, #DAYOFWEEK, #DATE )
-- Display
PRINT #TESTDATE
PRINT #DAY
PRINT #DAYOFWEEK
PRINT #DATE
Here is the non-system specific way to determine the first Sunday of the following month:
First, get the current month and add one month.
Next, set the date of that variable to be on the first.
Next, find the day value of that date (let's assume Mondays are 1 and Sundays are 7).
Next, subtract the day value of the 1st of the month from the day value of Sunday (7).
You now have the number of days between the first of the month and the first Sunday. You could then add that to the date variable to get the first Sunday, or, since we know the first of the month is 1, you could just add one to the difference (found in that last step above) and that is the date of the first Sunday. (You have to add one because it's subtracting and thus if the first of the given month IS Sunday, you'd end up with 0).
I have been looking through the T-SQL documentation and it is not at all intuitive as to how how you would use my method, but you will need the concept of "day of week number" to make it work no matter what.
This would be simplest with an auxiliary calendar table. See this link, for example.
However, it can be done without one, though it's rather tricky. Here I assume you want the first future date that is the first Sunday of a month. I've written this with a variable #now for - well - now, so it's easier to test. It might be possible to write more simply, but I think this has a better chance of being correct than quickly-written simpler solutions. [Corrected by adding DAY(d) < 8]
SET #now = GETDATE();
WITH Seven(i) AS (
SELECT -1 UNION ALL SELECT 0 UNION ALL SELECT 1
UNION ALL SELECT 3 UNION ALL SELECT 4
UNION ALL SELECT 5 UNION ALL SELECT 6
), Candidates(d) AS (
SELECT DATEADD(WEEK,i+DATEDIFF(WEEK,'19000107',#now),'19000107')
FROM Seven
)
SELECT TOP (1) d AS SoonestFutureFirstSunday
FROM Candidates
WHERE DAY(d) < 8 AND MONTH(d) >= MONTH(#now)
AND (MONTH(d) > MONTH(#now) OR DAY(d) > DAY(#now))
ORDER BY d; ORDER BY d;
I reckon that the answer is this
SELECT DATEADD(Month, DATEDIFF(Month, 0, GETDATE()) + 1, 0) + 6 - (DATEPART(Weekday,
DATEADD(Month,
DATEDIFF(Month,0, GETDATE()) + 1, 0))
+ ##DateFirst + 5) % 7 --FIRST sunday of following month

Get the last day of the month in SQL

I need to get the last day of the month given as a date in SQL. If I have the first day of the month, I can do something like this:
DATEADD(DAY, DATEADD(MONTH,'2009-05-01',1), -1)
But does anyone know how to generalize it so I can find the last day of the month for any given date?
From SQL Server 2012 you can use the EOMONTH function.
Returns the last day of the month that contains the specified date,
with an optional offset.
Syntax
EOMONTH ( start_date [, month_to_add ] )
How ... I can find the last day of the month for any given date?
SELECT EOMONTH(#SomeGivenDate)
Here's my version. No string manipulation or casting required, just one call each to the DATEADD, YEAR and MONTH functions:
DECLARE #test DATETIME
SET #test = GETDATE() -- or any other date
SELECT DATEADD(month, ((YEAR(#test) - 1900) * 12) + MONTH(#test), -1)
You could get the days in the date by using the DAY() function:
dateadd(day, -1, dateadd(month, 1, dateadd(day, 1 - day(date), date)))
Works in SQL server
Declare #GivenDate datetime
SET #GivenDate = GETDATE()
Select DATEADD(MM,DATEDIFF(MM, 0, #GivenDate),0) --First day of the month
Select DATEADD(MM,DATEDIFF(MM, -1, #GivenDate),-1) --Last day of the month
I know this is a old question but here is another solution that works for me
SET #dtDate = "your date"
DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#dtDate)+1,0))
And if some one is looking for different examples here is a link http://blog.sqlauthority.com/2007/08/18/sql-server-find-last-day-of-any-month-current-previous-next/
I hope this helps some one else.
stackoverflow Rocks!!!!
For SQL server 2012 or above use EOMONTH to get the last date of month
SQL query to display end date of current month
DECLARE #currentDate DATE = GETDATE()
SELECT EOMONTH (#currentDate) AS CurrentMonthED
SQL query to display end date of Next month
DECLARE #currentDate DATE = GETDATE()
SELECT EOMONTH (#currentDate, 1 ) AS NextMonthED
Based on the statements:
SELECT DATEADD(MONTH, 1, #x) -- Add a month to the supplied date #x
and
SELECT DATEADD(DAY, 0 - DAY(#x), #x) -- Get last day of month previous to the supplied date #x
how about adding a month to date #x and then retrieving the last day of the month previous to that (i.e. The last day of the month of the supplied date)
DECLARE #x DATE = '20-Feb-2012'
SELECT DAY(DATEADD(DAY, 0 - DAY(DATEADD(MONTH, 1, #x)), DATEADD(MONTH, 1, #x)))
Note: This was test using SQL Server 2008 R2
Just extend your formula out a little bit:
dateadd(day, -1,
dateadd(month, 1,
cast(month('5/15/2009') as varchar(2)) +
'/1/' +
cast(year('5/15/2009') as varchar(4)))
This works for me, using Microsoft SQL Server 2005:
DATEADD(d,-1,DATEADD(mm, DATEDIFF(m,0,'2009-05-01')+1,0))
WinSQL to get last day of last month (i.e today is 2017-02-09, returns 2017-01-31:
Select dateadd(day,-day(today()),today())
Try to run the following query, it will give you everything you want :)
Declare #a date =dateadd(mm, Datediff(mm,0,getdate()),0)
Print('First day of Current Month:')
Print(#a)
Print('')
set #a = dateadd(mm, Datediff(mm,0,getdate())+1,-1)
Print('Last day of Current Month:')
Print(#a)
Print('')
Print('First day of Last Month:')
set #a = dateadd(mm, Datediff(mm,0,getdate())-1,0)
Print(#a)
Print('')
Print('Last day of Last Month:')
set #a = dateadd(mm, Datediff(mm,0,getdate()),-1)
Print(#a)
Print('')
Print('First day of Current Week:')
set #a = dateadd(ww, Datediff(ww,0,getdate()),0)
Print(#a)
Print('')
Print('Last day of Current Week:')
set #a = dateadd(ww, Datediff(ww,0,getdate())+1,-1)
Print(#a)
Print('')
Print('First day of Last Week:')
set #a = dateadd(ww, Datediff(ww,0,getdate())-1,0)
Print(#a)
Print('')
Print('Last day of Last Week:')
set #a = dateadd(ww, Datediff(ww,0,getdate()),-1)
Print(#a)
WinSQL: I wanted to return all records for last month:
where DATE01 between dateadd(month,-1,dateadd(day,1,dateadd(day,-day(today()),today()))) and dateadd(day,-day(today()),today())
This does the same thing:
where month(DATE01) = month(dateadd(month,-1,today())) and year(DATE01) = year(dateadd(month,-1,today()))
This query can also be used.
DECLARE #SelectedDate DATE = GETDATE()
SELECT DATEADD(DAY, - DAY(#SelectedDate), DATEADD(MONTH, 1 , #SelectedDate)) EndOfMonth
--## Useful Date Functions
SELECT
GETDATE() AS [DateTime],
CAST(GETDATE() AS DATE) AS [Date],
DAY(GETDATE()) AS [Day of Month],
FORMAT(GETDATE(),'MMMM') AS [Month Name],
FORMAT(GETDATE(),'MMM') AS [Month Short Name],
FORMAT(GETDATE(),'MM') AS [Month No],
YEAR(GETDATE()) AS [Year],
CAST(DATEADD(DD,-(DAY(GETDATE())-1),GETDATE()) AS DATE) AS [Month Start Date],
EOMONTH(GETDATE()) AS [Month End Date],
CAST(DATEADD(M,-1,DATEADD(MM, DATEDIFF(M,0,GETDATE()),0)) AS DATE) AS [Previous Month Start Date],
CAST(DATEADD(S,-1,DATEADD(MM, DATEDIFF(M,0,GETDATE()),0)) AS DATE) AS [Previous Month End Date],
CAST(DATEADD(M,+1,DATEADD(MM, DATEDIFF(M,0,GETDATE()),0)) AS DATE) AS [Next Month Start Date],
CAST(DATEADD(D,-1,DATEADD(MM, DATEDIFF(M,0,GETDATE())+2,0)) AS DATE) AS [Next Month End Date],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE()),0) AS DATE) AS [First Day of Current Week],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE())+1,-1) AS DATE) AS [Last Day of Current Week],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE())-1,0) AS DATE) AS [First Day of Last Week],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE()),-1) AS DATE) AS [Last Day of Last Week],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE())+1,0) AS DATE) AS [First Day of Next Week],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE())+2,-1) AS DATE) AS [Last Day of Next Week]
My 2 cents:
select DATEADD(DAY,-1,DATEADD(MONTH,1,DATEADD(day,(0-(DATEPART(dd,'2008-02-12')-1)),'2008-02-12')))
Raj
using sql server 2005, this works for me:
select dateadd(dd,-1,dateadd(mm,datediff(mm,0,YOUR_DATE)+1,0))
Basically, you get the number of months from the beginning of (SQL Server) time for YOUR_DATE. Then add one to it to get the sequence number of the next month. Then you add this number of months to 0 to get a date that is the first day of the next month. From this you then subtract a day to get to the last day of YOUR_DATE.
Take some base date which is the 31st of some month e.g. '20011231'. Then use the
following procedure (I have given 3 identical examples below, only the #dt value differs).
declare #dt datetime;
set #dt = '20140312'
SELECT DATEADD(month, DATEDIFF(month, '20011231', #dt), '20011231');
set #dt = '20140208'
SELECT DATEADD(month, DATEDIFF(month, '20011231', #dt), '20011231');
set #dt = '20140405'
SELECT DATEADD(month, DATEDIFF(month, '20011231', #dt), '20011231');
Using SQL Server, here is another way to find last day of month :
SELECT DATEADD(MONTH,1,GETDATE())- day(DATEADD(MONTH,1,GETDATE()))
I wrote following function, it works.
It returns datetime data type. Zero hour, minute, second, miliseconds.
CREATE Function [dbo].[fn_GetLastDate]
(
#date datetime
)
returns datetime
as
begin
declare #result datetime
select #result = CHOOSE(month(#date),
DATEADD(DAY, 31 -day(#date), #date),
IIF(YEAR(#date) % 4 = 0, DATEADD(DAY, 29 -day(#date), #date), DATEADD(DAY, 28 -day(#date), #date)),
DATEADD(DAY, 31 -day(#date), #date) ,
DATEADD(DAY, 30 -day(#date), #date),
DATEADD(DAY, 31 -day(#date), #date),
DATEADD(DAY, 30 -day(#date), #date),
DATEADD(DAY, 31 -day(#date), #date),
DATEADD(DAY, 31 -day(#date), #date),
DATEADD(DAY, 30 -day(#date), #date),
DATEADD(DAY, 31 -day(#date), #date),
DATEADD(DAY, 30 -day(#date), #date),
DATEADD(DAY, 31 -day(#date), #date))
return convert(date, #result)
end
It's very easy to use.
2 example:
select [dbo].[fn_GetLastDate]('2016-02-03 12:34:12')
select [dbo].[fn_GetLastDate](GETDATE())
Based on the most voted answer at below link I came up with the following solution:
declare #mydate date= '2020-11-09';
SELECT DATEADD(month, DATEDIFF(month, 0, #mydate)+1, -1) AS lastOfMonth
link: How can I select the first day of a month in SQL?
I couldn't find an answer that worked in regular SQL, so I brute forced an answer:
SELECT *
FROM orders o
WHERE (MONTH(o.OrderDate) IN ('01','03','05','07','08','10','12') AND DAY(o.OrderDate) = '31')
OR (MONTH(o.OrderDate) IN ('04','06','09','11') AND DAY(o.OrderDate) = '30')
OR (MONTH(o.OrderDate) IN ('02') AND DAY(o.OrderDate) = '28')
---Start/End of previous Month
Declare #StartDate datetime, #EndDate datetime
set #StartDate = DATEADD(month, DATEDIFF(month, 0, GETDATE())-1,0)
set #EndDate = EOMONTH (DATEADD(month, DATEDIFF(month, 0, GETDATE())-1,0))
SELECT #StartDate,#EndDate