Reputation: 1195
I'm hoping to find a solution for this to automate a report I have. Basically what I'm trying to accomplish here is grabbing a date (first day of previous month, two years ago through last day of previous month current year).
So the date span if running this month would look like this: between 4/1/2013 and 3/31/2015
I have found code to get the date two years ago but I'm not able to also incorporate the month functions... Any help is very much appreciated!
For year I'm using this:
SELECT CONVERT(VARCHAR(25),DATEADD(year,-2,GETDATE()),101)
Upvotes: 1
Views: 4124
Reputation: 1270553
Your where
clause can look something like this:
where date >= cast(dateadd(year, -2,
dateadd(month, -1, getdate() - day(getdate()) + 1)
) as date) and
date < cast(getdate() - day(getdate()) + 1 as date)
This makes use of the handy convenience that subtracting/adding a number to a datetime
is the same as adding a date. The start date says: get the first day of the month, then subtract one month, then subtract two years. This could have been done as dateadd(month, -25, . . .)
, but I think separating the logic is clearer.
Upvotes: 1
Reputation: 74317
Given a reference date (e.g. "today"),
declare @today date = '23 April 2015'
The 1st of the month is computed by subtracting 1 less than the day number of the current month:
select first_of_current_month = dateadd(day,1-day(@today),@today)
The last day of the previous month is day 0 of the current month, so to get the last day of the previous month, just subtract the current day number:
select last_of_previous_month = dateadd(day,-day(@today),@today)
Moving two years back is easy:
select two_years_back = dateadd(year,-2, @today )
Putting it all together, this should do you:
declare @today date = '23 April 2015'
select *
first_day_of_current_month = dateadd(day,1-day(@today),@today),
last_day_of_previous_month = dateadd(day, -day(@today),@today) ,
date_from = dateadd(year,-2, dateadd(day,1-day(@today),@today) ) ,
date_thru = dateadd(day, -day(@today),@today)
yielding the expected results:
first_day_of_current_month: 2015-04-01
last_day_of_previous_month: 2015-03-31
date_from : 2013-04-01
date_thru : 2015-03-31
So you should be able to say something like this:
select *
from foo t
where t.transaction_date between dateadd(year,-2, dateadd(day,1-day(@today),@today) )
and dateadd(day, -day(@today),@today)
If you have to deal with datetime
values rather than date
, its easier to not use between
and say something like this:
declare @today date = current_timestamp -- get the current date without a time component
select *
from foo t
where t.transaction_date >= dateadd(year,-2, dateadd(day,1-day(@today),@today) )
and t.transaction_date < dateadd(year, 0, dateadd(day, -day(@today),@today)
[superfluous addition of 0 years added for clarity]
Upvotes: 0
Reputation: 1291
This gives you two dates you are looking for:
SELECT
CAST((DATEADD(yy, -2, DATEADD(d, -1 * DATEPART(dd, getdate()) + 1 , GETDATE() ))) as date) as yourTwoYearsAgoDate,
CAST((DATEADD(d, -1 * DATEPART(dd, GETDATE()), GETDATE())) as date) as yourEndOfLastMonthDate
Upvotes: 0
Reputation: 99
First day of previous month 2 years ago:
SELECT CONVERT(DATE,dateadd(day, -1, dateadd(day, 1 - day(GETDATE()), GETDATE())))
Last day of last month:
SELECT CONVERT(DATE,DATEADD(month, DATEDIFF(month, 0, DATEADD(year,-2,GETDATE())), 0))
Then just do whatever logic you need with them
Upvotes: 1