How to use Date range in the WHERE clause - sql

I want to modify my Where clause in my SQL Server Query below so that it would select ALL records from the previous month.
Example: if I run the query on 20 Feb, it should extract data for 1 Jan to 31 Jan
I have tried using the following but as you may notice, it picks up the records a month back from the day of execution.
WHERE date_col >= cast(dateadd(Month, -1, getdate()) as date) and
date_col <= cast(getdate() as date)

I'm not claiming this is the best way, but it should work:
SELECT * from YourTable
WHERE DATEPART(Month, date_col) = (DATEPART(Month,GETDATE()) - 1)
AND DATEPART(Year, date_col) = DATEPART(Year,DATEADD(Month, -1, GETDATE()))

Sql Server 2012 and Later
EOMONTH looks like it may be a useful function in this case.
EOMONTH(getdate(), -1) is the end of last month.
EOMONTH(getdate(), -2) is the end of the month before.
Try something like
WHERE date_col >= cast(EOMONTH(getdate(), -1) as date) and date_col <=
cast(EOMONTH(getdate(),-2) as date);

TO get the last and first day of previous month :
SELECT DATEADD(month, DATEDIFF(month, 0, DATEADD(MONTH,-1,GETDATE())), 0) AS First_Day_Of_Last_Month
,DATEADD(s,-1,DATEADD(MONTH, DATEDIFF(MONTH,0,GETDATE()),0)) AS Last_day_Of_Last_Month
Result:
╔═════════════════════════╦═════════════════════════╗
║ First_Day_Of_Last_Month ║ Last_day_Of_Last_Month ║
╠═════════════════════════╬═════════════════════════╣
║ 2014-05-01 00:00:00.000 ║ 2014-05-31 23:59:59.000 ║
╚═════════════════════════╩═════════════════════════╝
Your Query
WHERE date_col >= DATEADD(month, DATEDIFF(month, 0, DATEADD(MONTH,-1,GETDATE())), 0)
AND date_col <= DATEADD(s,-1,DATEADD(MONTH, DATEDIFF(MONTH,0,GETDATE()),0))

Since you want all records from the previous month, you could just compare the month and year parts of the current date and the date_col values, like so:
select *
from yourtable
where
(month(date_col) = month(getdate()) - 1
and year(date_col) = year(getdate())
and month(getdate()) <> 1)
or
(month(date_col) = 12
and year(date_col) = year(getdate()) - 1
and month(getdate()) = 1)

This query also work as already ask by some one and good rating of answer too.
SELECT *
FROM Member
WHERE DATEPART(m, date_created) = DATEPART(m, DATEADD(m, -1, getdate()))
AND DATEPART(yyyy, date_created) = DATEPART(yyyy, DATEADD(m, -1, getdate()))
Get the records of last month in SQL server

Related

How to return values of two date ranges, from the same date column and value column, in two different columns as a result?

I have following data in my table,
Table = BillHeader
Sales column = Sales
Date column = CreateDate
Location name = Location
Result needed:
Location
Sum_of_Sale_1
Sum_of_Sale_2
Sum_of_Sale_1 = Sum of Sales up to yesterday for this month.
Sum_of_Sale_2 = Sum of Sales up to same date range as Sum_of_Sale_1 during last month.
For example, if today is 20th of June, Sum_of_Sale_1 = Sum of sales from 1st June to 19th of June
and Sum_of_Sale_2 = Sum of sales from 1st May to 19th of May.
Basically what I need is these two results of different date ranges, which should be selected form the same three columns, should appear next to each other in the result. I want to know how the sales performance was last month's same date range as to this month's date range (up to yesterday for this month).
Thanks!!
EDIT - 1
Here is the actual current working code:
SET #FDM = DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0)
SELECT sum ([LAB_TRN_BillHeader].[AmountToBePaid]) as Total_Sale
,LAB.dbo.[LAB_TRN_BillHeader].[CollectingCenterCode]
,LAB.dbo.[LAB_Comm_MST_CollectingCenter].[Name]
,LAB.dbo.[LAB_Comm_MST_Branch].[BranchName]
FROM Lab.dbo.[LAB_TRN_BillHeader]
INNER JOIN LAB.dbo.[LAB_Comm_MST_CollectingCenter] on LAB.dbo.[LAB_TRN_BillHeader].[CollectingCenterCode] = LAB.dbo.[LAB_Comm_MST_CollectingCenter].[CollectingCenterCode]
INNER JOIN LAB.dbo.[LAB_Comm_MST_Branch] on LAB.dbo.[LAB_TRN_BillHeader].[BranchCode] = LAB.dbo.[LAB_Comm_MST_Branch].[BranchCode]
WHERE Date between #FDM and DATEADD(day,0, CAST(GETDATE() AS date)) and {{select_Laboratory}} and LAB.dbo.[LAB_TRN_BillHeader].[IsVoid] = '0' and LAB.dbo.[LAB_TRN_BillHeader].[CollectingCenterCode] in ('URCR022','MRPMC','KUCC','KOCC','EHECC')
GROUP BY LAB.dbo.[LAB_TRN_BillHeader].[CollectingCenterCode], LAB.dbo.[LAB_Comm_MST_CollectingCenter].[Name], LAB.dbo.[LAB_Comm_MST_Branch].[BranchName]
Current Result:
|Total_Sale|CollectingCenterCode|Name|BranchName|
|xxx |xxx |x |xx |
Required Result:
|Total_Sale|Total_Sale2|CollectingCenterCode|Name|BranchName|
|xxx |xxx |xx |x |xx |
Total_Sale = Sale of current month up to yesterday
Total_Sale2 = Sale of Last month up to current month's yesterday's date.
-- MSSQL Version - 2014
-- <Create_Date> is a time stamp in the table in <Create_Date> column. The date/time is obtained from that timestamp. Each transaction is saved with a respective timestamp at it's time of occurrence.
-- {{select_Laboratory}} is a field filter alias in Metabase (this code was copied from a Metabase dashboard). The actual code is LAB.dbo.[LAB_TRN_BillHeader].[BranchCode] = '001'
Considering a sales CreateDate is likely of type Datetime or Datetime2, a safe approach would be:
DECLARE #yesterday DATE = GETDATE();
DECLARE #lastMonth DATE = DATEADD(MONTH, -1, #yesterday);
DECLARE #firstDayOfThisMonth DATE = DATEADD(DAY, 1 - DAY(#yesterday), #yesterday);
DECLARE #firstDayOfLastMonth DATE = DATEADD(DAY, 1 - DAY(#lastMonth), #lastMonth);
SELECT #yesterday,
#firstDayOfThisMonth,
#lastMonth,
#firstDayOfLastMonth;
SELECT [locationId],
SUM( CASE
WHEN CreateDate >= #firstDayOfThisMonth
AND CreateDate < #yesterday THEN
AmountToBePaid
END
) AS Sum_of_Sale_1,
SUM( CASE
WHEN CreateDate >= #firstDayOfLastMonth
AND CreateDate < #lastMonth THEN
AmountToBePaid
END
) AS Sum_of_Sale_2
FROM BillHeader
GROUP BY [locationId];
EDIT: Note that in dates like March 31,30 previous month's end date could be Feb 28, 29.
You could use conditional aggregation with the following date functions:
DATEADD(Day, 1, EOMONTH(GETDATE(), -1)) gets the first date of the current month, i.e. current month is Jan-2023 it will return '2023-01-01'.
CAST(GETDATE() AS DATE) gets today's date.
DATEADD(Day, 1, EOMONTH(GETDATE(), -2)) gets the first date of the previous month, i.e. current month is Jan-2023 it will return '2022-12-01'.
DATEADD(Month, -1, CAST(GETDATE() AS DATE) gets the date of the day one-month pre today's date.
SELECT Location,
SUM(CASE
WHEN CreateDate >= DATEADD(Day, 1, EOMONTH(GETDATE(), -1)) AND
CreateDate < CAST(GETDATE() AS DATE)
THEN Sales END) Sum_of_Sale_1,
SUM(CASE
WHEN CreateDate >= DATEADD(Day, 1 ,EOMONTH(GETDATE(), -2)) AND
CreateDate < DATEADD(Month, -1, CAST(GETDATE() AS DATE))
THEN Sales END) Sum_of_Sale_2
FROM BillHeader
GROUP BY Location
See demo
There are different ways of doing the calculations and I don't know if this logic will seem more straightforward or as concise. Also you might not be able to use variables. Lastly, you didn't specify which version you're running.
Although you can incorporate this into an existing query that covers a wider range of dates, here is a stand-alone option that should restrict the execution to a narrower range of dates. The case logic, as written, does assume that rows have already been filtered so the only thing left to determine is whether the sale comes from current month or prior month.
select Location,
sum(case when month(CreateDate) <> month(getdate()) then Sales end) as Sales1,
sum(case when month(CreateDate) = month(getdate()) then Sales end) as Sales2
from BillHeader
where
-- go back enough days to guarantee covering last two months
-- this may be able to utilize an index
SalesDate between dateadd(day, -30 - day(getdate()), cast(getdate() as date))
and getdate()
-- now eliminate extra dates that are not relevant
and month(getdate()) - month(CreateDate) in (0, 1, -11) /* year might roll over */
and day(getdate()) > day(CreateDate)
group by Location;
For a YOY comparison over the same calendar month:
select Location,
sum(case when year(CreateDate) <> year(getdate()) then Sales end) as Sales1,
sum(case when year(CreateDate) = year(getdate()) then Sales end) as Sales2
from BillHeader
where
-- go back enough days to guarantee covering last 13 months
-- (or rewind as 396 days via parallel logic from earlier)
SalesDate between
dateadd(year, -1, dateadd(day, 1 - day(getdate()), cast(getdate() as date)))
and getdate()
and month(getdate()) = month(CreateDate)
and day(getdate()) > day(CreateDate)
group by Location;
This might be better done as a union with two different date ranges combined together:
-- ...
where
SalesDate between
dateadd(year, -1, dateadd(day, 1 - day(getdate()), cast(getdate() as date)))
and dateadd(year, -1, getdate())
-- ... union all ...
where
SalesDate between
dateadd(day, 1 - day(getdate()), cast(getdate() as date))
and getdate()
-- ...

What is SQL Server statement to get day and month ignoring the current year?

I have table HD_Case_Master with a column cm_date_created.
The example value is 2011-05-13 10:07:36.000.
I manage to get the current year but how to get record for all day and month.
SQL statement:
SELECT
cm_create_date
FROM
HD_Case_Master
WHERE
YEAR(cm_create_date) = YEAR(GETDATE()) AND ???
If you want the current date:
SELECT cm_create_date
FROM HD_Case_Master
WHERE cm_create_date >= CAST(GETDATE() as date) AND
cm_create_date < CAST(DATEADD(day, 1, GETDATE()) as date)
If you want to check if cm_date_created is equal to the current date, ignoring the time component, you just need to CAST both dates to DATE:
SELECT *
FROM HD_Case_Master
WHERE
CAST(cm_create_date AS DATE) = CAST(GETDATE() AS DATE)
Alternatively, you can use >= and < to check if cm_date_created falls within the current date:
SELECT *
FROM HD_Case_Master
WHERE
cm_create_date >= CAST(GETDATE() AS DATE)
AND cm_create_date < CAST(DATEADD(DAY, 1, GETDATE()) AS DATE)
You can use DATEPART function of tsql.
... Where DATEPART(day, cm_create_date) = DATEPART(day, getdate()) AND DATEPART(month, cm_create_date) = DATEPART(month, getdate())
You were really close! To add just the month (but ignoring the year), just use this:
SELECT
cm_create_date
FROM
HD_Case_Master
WHERE
YEAR(cm_create_date) = YEAR(GETDATE())
AND MONTH(cm_create_date) = MONTH(GETDATE())

How to get the Next months results from date field

I have a table with a date.
I need to get all results for the upcoming month.
*******Sample Code I have but it returns 2 months of data**********
where worktype = 'mpm' and status = 'active'
and (nextdate >= DATEADD(MONTH,01,GETDATE()))
and (nextdate < DATEADD(MONTH,02,GETDATE()))
Some Data:
2016-01-27 00:00:00.000
2016-01-28 00:00:00.000
2016-02-02 00:00:00.000
2016-02-02 00:00:00.000
It is returning 2 months of data.
Your results are returning exactly what you've requested. You're requesting to get anything within the date range of One Month from Today and Two Months from Today.
All of your results are within that range.
If you are only interested in the data that is within the next calendar month (at the time of writing, January 2016), this would suit you better:
Where worktype = 'mpm'
And status = 'active'
And nextdate Between
DateAdd(Month, -1, DateAdd(Month, DateDiff(Month, 0, GetDate()) +2, 0))
And DateAdd(Day, -1, DateAdd(Month, DateDiff(Month, 0, GetDate()) +2, 0))
If you are using SQL Server 2012 or later, you can also use the following:
Where worktype = 'mpm'
And status = 'active'
And nextdate Between
DateAdd(Day, 1, EOMonth(Current_Timestamp))
And EOMonth(DateAdd(Day, 1, EOMonth(Current_Timestamp))
Something like this maybe:
WHERE DATEPART(MONTH, nextdate) = DATEPART(MONTH,DATEADD(MONTH,1,GETDATE()))

Why do I get different results with this SQL Date Part and date parameters

When I run this where clause on my table I get 2 different results and to me its seems like I should get the same number of records back.
The one I'm using just a static date to test and the other should also retrieve the same results where I'm trying to get last month results
I idea the query is a report that will automatic load the previous months records.
WHERE
(OrderReceiptedDate >= '2015-03-01')
AND (OrderReceiptedDate <= '2015-03-31')
WHERE
(DATEPART(mm, OrderReceiptedDate) = DATEPART(mm, DATEADD(mm, - 1, GETDATE())))
AND
(DATEPART(yy, OrderReceiptedDate) = DATEPART(yy, DATEADD(mm, - 1, GETDATE())))
These are the two statements
WHERE (OrderReceiptedDate >= '2015-03-01' AND
OrderReceiptedDate <= '2015-03-31'
)
WHERE (DATEPART(month, OrderReceiptedDate) = DATEPART(month, DATEADD(month, - 1, GETDATE()))) AND
(DATEPART(year, OrderReceiptedDate) = DATEPART(year, DATEADD(month, - 1, GETDATE())))
Given that today is April 2015, you are expecting that both of these get all dates for March. And, they would, if your dates had no time components. The problem is that almost any datetime on March 31st is not going to match the first condition. The one exception is exactly at midnight: 2015-03-01 00:00:00.000.
The first is better written as:
WHERE (OrderReceiptedDate >= '2015-03-01' AND
OrderReceiptedDate < '2015-04-01'
)
A better way to write "get me last months date" is something like:
WHERE OrderReceiptedDate >= dateadd(month, -1, cast(getdate() - day(getdate()) + 1 as date)) and
OrderReceiptedDate < cast(getdate() - day(getdate()) + 1 as date)
This does all the calculations on getdate() so the query could still take advantage of an index on OrderReceiptDate.

Keyword for "Last Month" in SQL Server 2008

I have a query (pasted below), and I would like to make it so that people don't need to update the completed date range. I would like for it to automatically just get results from last month. So if it is run in February, for example, it will give me results for all completed items that meet my criteria for January. Can anyone think of a way to do that?
select External_ID__c,
Ewrk_Tracking_Number__c,
PIF_Branch_Name,
Distribution_Branch_Name,
Transaction_Type__C,
submitter_date__c, Completed_Date__C,
COUNT(External_ID__c)
from Business_Solutions_D.dbo.Reporting_SalesForce_AspireBaseData
where PIF_Branch_Code = 977
and Completed_Date__C >= '2015-01-01'
and Completed_Date__C < '2015-02-01'
and Delete_Flag__C = 'FALSE'
group by External_ID__c,
Ewrk_Tracking_Number__c,
PIF_Branch_Name,
Distribution_Branch_Name,
Transaction_Type__C,
submitter_date__c,
Completed_Date__C
There is no "keyword" for last month. You have to put that in your predicates.
Here is an example of how to get some date values for this.
select dateadd(MONTH, datediff(MONTH, 0, GETDATE()), 0) as BeginningOfThisMonth
select dateadd(MONTH, datediff(MONTH, 0, GETDATE()) - 1, 0) as BeginningOfPreviousMonth
If you want to see a number of other date routines here is an excellent blog post with quite a few of them. http://www.sqlservercentral.com/blogs/lynnpettis/2009/03/25/some-common-date-routines/
If you mean the last month prior to this one, you can do it in two steps: first, find the first day of the current month
#firstDayOfThisMonth = DATEADD(day, DAY(GETDATE())-1, GETDATE())
then subtract one month:
#firstDayOfLastMonth = DATEADD(month, -1, #firstDayOfThisMonth)
Then your query would be:
and Completed_Date__C >= #firstDayOfLastMonth
and Completed_Date__C < #firstDayOfThisMonth
Another way would be to query where the difference (in months) between Completed_Date__C and the current date is 1:
and DATEDIFF(Completed_Date__C, GETDATE()) = 1
You can do this with date arithmetic. One trick to get the first date of the month is to subtract the current day of the month from the date and add one day. SQL Server allows you to do this with + and - instead of dateadd(), on a datetime value. Of course, you need to remove the time component as well (using cast( as date)).
The logic looks like this for the current month:
where Completed_Date__C >= cast(getdate() - day(getdate()) + 1 as date) and
Completed_Date__C < dateadd(month, 1, cast(getdate() - day(getdate()) + 1 as date))
And like this for the previous month:
where Completed_Date__C >= dateadd(month, -1, cast(getdate() - day(getdate()) + 1 as date)) and
Completed_Date__C < cast(getdate() - day(getdate()) + 1 as date)
This has the nice property that it is a sargeable as your original code, so it will take advantage of an index on the column, if appropriate.
You just need to have it do some date math to calculate it.
--Go to last day of prev month - 'Day' to account for varying month day counts
and Completed_Date__C >= GETDATE() - DATEPART(DAY, GETDATE()) - DATEPART(DAY, GETDATE() - DATEPART(DAY, GETDATE())) + 1
and Completed_Date__C < GETDATE() - DATEPART(DAY, GETDATE()) + 1
When you do additions on DateTimes + integer it assumes it day based addition.