Retrieving last months data when last month is also last year? - sql

I have the following Where clause in several queries. This successfully retrieves the past months data. Now the year has changed, the query can't find any data (December 2018 hasn't happened yet!). How can I change the Where clause to overcome this?
select *
from somedatabase a
WHERE DATEPART(m, a.meetDate) = DATEPART(m, DATEADD(m, -1, getdate()))
and DATEPART(yyyy, a.meetDate) = DATEPART(yyyy, getdate())
Many thanks and any assistance very gratefully received.

My normal way of rounding down to the start of the current month is:
DATEADD(month, DATEDIFF(month, 0, getDate()), 0)
Find out how many whole months there have been since date 0
Then add that many months to date 0
Always gives the start of the month (as date 0 is the start of a month)
Is not affected by leap year, year boundaries, months of various length, etc
This then allows me to do things like...
WHERE
a.meetDate >= DATEADD(month, DATEDIFF(month, 0, getDate()) - 1, 0) -- start of last month
AND a.meetDate < DATEADD(month, DATEDIFF(month, 0, getDate()) , 0) -- start of this month
By having the calculations on the right hand side you make maximum use of indexes.

Here is one way:
WHERE DATEPART(month, a.meetDate) = DATEPART(month, DATEADD(m, -1, getdate())) AND
DATEPART(year, a.meetDate) = DATEPART(year, DATEADD(m, -1, getdate()))
That is, subtract one month for both comparisons.
Actually, a simpler way is to use the strange rules of DATE_DIFF():
WHERE DATEDIFF(month, a.meetDate, getdate()) = 1
Neither of these can make use of an index. For that, the expression is a little more complicated:
WHERE a.meetDate >= DATEFROMPARTS(YEAR(DATEADD(MONTH, -1, GETDATE()),
MONTH(DATEADD(MONTH, -1, GETDATE()),
1) AND
a.meetDate < DATEADD(DAY, 1 - DAY(GETDATE()), CAST(GETDATE() as DATE))

Related

Get date for Saturday two weeks ago

I'm currently building a query which needs to show data from Saturday to Friday. For example, running the query today you should get data from 7/24 to 7/30. I’m seeing data from 7/25 to 7/30 and I frankly don’t know how to fix the code below to get Saturday’s data as well.
Here’s what I have:
WHERE
InvoiceDate BETWEEN DATEADD(WEEK, -2, DATEADD(WEEK, DATEDIFF(WEEK, 5, GETDATE()), 5))
AND DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()), 0))
Preferably, I’d like to keep the similar format rather than parameterizing the query. Unless that’s a better idea of course! I’m also asking this on my phone so I apologize for not including the entire query. However because it is in the where clause, I figured the rest wasn’t needed.
you're leaving out a lot of information so assuming that you are running this query every Monday (as of my reply, today is Monday) and you are just going back to last-last Saturday to last Friday, your WHERE clause can be quite simple:
where InvoiceDate between dateadd(day,-9,getdate()) and dateadd(day,-3,getdate())
if there are are more criteria or conditions then let us know.
try the following query, just put the date whenever you need
SELECT
case
when datepart(weekday, '2021/08/03') >5
then DATEADD(DAY, +4, DATEADD(WEEK, DATEDIFF(WEEK, 0, '2021/08/03'), 0))
else DATEADD(DAY, -9, DATEADD(WEEK, DATEDIFF(WEEK, 0, '2021/08/03'), 0))
end AS last_saturday,
case
when datepart(weekday, '2021/08/03') >5
then DATEADD(DAY, +4, DATEADD(WEEK, DATEDIFF(WEEK, 0, '2021/08/03'), 0))
else DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, '2021/08/03'), 0))
end AS last_friday;
I realize you have an answer already, but this will allow you to use whatever date you want. Using the day of the week to subtract days from today will give you the previous Saturday. Subtracting 7 from that will give you the Saturday a week ago.
So given that, the below will search the range from the start of a week ago Saturday until the start of this previous Saturday. This works with both date and datetime data types.
WHERE InvoiceDate >= DATEADD(day, -7 + DATEPART(dw,GETDATE()) * -1, GETDATE())
AND InvoiceDate < DATEADD(day, DATEPART(dw,GETDATE()) * -1, GETDATE())

Get records of last 2 months (current year), and last month(last year)

I need to get records of last 2 months and last month(last year) based on my table field paidDate, using SQL server 2016.
Suppose, I run the query on Feb 1st/2nd, 2020. I need the monthly data from December 2019, January 2020, as well as January 2019.
What's the SQL query for this? Is it possible to club all of these scenario into one?
Then for the previous 2 months the paidDate would be :
A) Higher or equal than the first day of 2 months ago
B) Lower than the first day of the current month.
Similar for the month of a year ago.
So try something like this:
SELECT *
FROM YourTable
WHERE
(
paidDate >= DATEADD(month, -2, DATEADD(month, DATEDIFF(month, 0, GetDate()), 0))
AND paidDate < DATEADD(month, DATEDIFF(month, 0, GetDate()), 0)
)
OR
(
paidDate >= DATEADD(month, -13, DATEADD(month, DATEDIFF(month, 0, GetDate()), 0))
AND paidDate < DATEADD(year, -1, DATEADD(month, DATEDIFF(month, 0, GetDate()), 0))
)
LukStorm has the better answer in terms of performance (and I've upvoted it). But if you want complete months and don't care about indexing, then I would suggest datediff():
where datediff(month, paiddate, getdate()) in (1, 2, 13)
This gets the complete months that are 1 month, 2 months, and 13 months in the past.
You can try the logic as below-
SELECT *
FROM your_table
WHERE
(
YEAR(paidDate) = YEAR(DATEADD(MM,-1, getdate()))
AND
MONTH(paidDate) = MONTH(DATEADD(MM,-1, getdate()))
)
OR
(
YEAR(paidDate) = YEAR(DATEADD(MM,-2, getdate()))
AND
MONTH(paidDate) = MONTH(DATEADD(MM,-2, getdate()))
)
OR
(
YEAR(paidDate) = YEAR(DATEADD(MM,-13, getdate()))
AND
MONTH(paidDate) = MONTH(DATEADD(MM,-13, getdate()))
)

How can I get the last 12 months from the current date PLUS extra days till 1st of the last month retrieved

Getting the last 12 months from a specific date is easy and can be retrieved by the following command in SQL-server. Its answer is 2014-08-17.
select Dateadd(Month, -12, '2015-08-17')
What I want is to get the last 12 months but ending at 2014-08-01 (in the above case) instead of any where in the middle of the month.
SELECT dateadd(month,datediff(month,0,getdate())-12,0)
Result is
-----------------------
2014-08-01 00:00:00.000
So the where clause should be
WHERE datecol >=dateadd(month,datediff(month,0,getdate())-12,0)
to get all data starting from jan 01 of last year's same month
Using DATEADD and DATEDIFF:
DECLARE #ThisDate DATE = '20150817'
SELECT DATEADD(YEAR, -1, DATEADD(MONTH, DATEDIFF(MONTH, '19000101', #ThisDate), '19000101'))
For more common date routines, see this article by Lynn Pettis.
To use in your WHERE clause:
DECLARE #ThisDate DATE = '20150817'
SELECT *
FROM <your_table>
WHERE
<date_column> >= DATEADD(YEAR, -1, DATEADD(MONTH, DATEDIFF(MONTH, '19000101', #ThisDate), '19000101'))
If you want all the records since the first day of the current month last year, then you can use:
where <somedate> >= dateadd(day, 1 - day(dateadd(month, -12, getdate()),
dateadd(month, -12, getdate()))
For all days except Feb 29th, you can use the simpler:
where <somedate> >= dateadd(day, 1 - day(getdate()),
dateadd(month, -12, getdate))

Last 13 full months SQL WHERE clause

I have a database with a date column that logs when a new "contact" is created. The contacts are generated when the call center receives a new call or e-mail.
What I want is for the where clause to capture the last 13 months of full data.
Examples:
Today is 1/30/2015, if executed the query would return records from 12/1/2013 to 12/31/2014.
Today is 2/06/2015, if executed the query would return records from 1/1/2014 to 1/31/2015.
The query will include those dates falling on the first and last days of the month.
The code I have is as follows:
WHERE
dbo.ub_contact.contact_dt BETWEEN DATEADD(year, -1, (DATEADD(month, DATEDIFF(month, -1, getdate()) - 1, -1) + 1))
AND DATEADD(month, DATEDIFF(month, -1, getdate()) - 1, -1)
Ran today (1/30/2015) this code seems to be returning 1/1/2014 - 12/31/2014.
I would appreciate any help toward getting this worked out.
Thanks!
John
Use this dates:
SELECT EOMONTH(DATEADD(mm, -1, GETDATE()))
SELECT DATEADD(dd, 1, EOMONTH(DATEADD(mm, -14, GETDATE())))
So you where clause would look like:
WHERE dbo.ub_contact.contact_dt BETWEEN DATEADD(dd, 1, EOMONTH(DATEADD(mm, -14, GETDATE()))) AND EOMONTH(DATEADD(mm, -1, GETDATE()))

How to select results where it was inserted on X day of the week for the last X months?

I have to collect all the rows in a table where they were inserted on a Monday for the last 3 three months. How would I write the WHERE clause date to get those results?
WHERE Date = (wk, DATEDIFF(wk,0,GETDATE()), 0)
That will select everything from Monday of the current week, but what I am having a problem with is selecting a range of Mondays going back three months.
thanks!
So this is the WHERE clause I ended up with that works well for me....
where Datestamp > dateadd(month, -3, getdate())
AND datepart(weekday, Datestamp) = datepart(weekday, DATEADD(wk, DATEDIFF(wk,0,GETDATE()), 0))
I changed only the part where we enter the day of the week that starts on Monday I added this...
DATEADD(wk, DATEDIFF(wk,0,GETDATE()), 0)
WHERE Date > dateadd(month, -3, getdate())
AND datepart(weekday, Date) = 1
These are two separate conditions; no need to compress them into one.
Note: run a test on your machine to see which value you get for datepart(weekday, #AMondayDate). On some systems Monday is 1, on others is 2; it depends on the DATEFIRST configuration.
Update:
Thanks to ErikE for the clever trick that overcomes the weekday numbers issue:
WHERE Date > dateadd(month, -3, getdate())
AND datepart(weekday, Date) = datepart(weekday, '2012-11-25')