Date Specific Criteria for Query - sql

I have a query that is gathering data from the 20th of last month to the 19th of this month and it seems to be working.
(DateTime >= 19+dateadd(mm,datediff(mm,0,getdate())-1,0)
AND DateTime < 18+dateadd(mm,datediff(mm,0,getdate()),0))
I now need to somehow modify it to meet the following...
Always show the current report no matter when it is run.
Currently what happens is.....it works great if run anytime between the 20th of last month and the 19th of this month.....but as soon as it hits the 20th of this month through the 31th of this month....it keeps showing the last period....which technically i am asking it to do.
What I need is.....When it becomes the 20th of this month....it starts a new report.
As I said.....the problem period is between the 20th and the end of the month. Once the new month starts....everything is fine.
It somehow has to take into account when the report is being run.
Thanks.
Dave

Dave, I think that this may work for you.
(
(Day(GetDate()) > 19 and create_date between dateadd(mm, datediff(mm, 0, getdate()), 0) + 19 and dateadd(mm, datediff(mm, 0, getdate()), 0) + 18)
or (Day(GetDate()) < 20 and create_date between dateadd(mm, datediff(mm, 0, getdate())-1, 0) + 19 and dateadd(mm, datediff(mm, 0, getdate())-1, 0) + 18)
)
It essentially checks to see that the current day is greater than 19 and applies your current logic without subtracting a month. I the current day is less than the 20th your current logic is applied.

(
DateTime >= CASE WHEN day(GETDATE()) >= 20 THEN 19 + dateadd(mm, datediff(mm, 0, getdate()), 0) ELSE 19 + dateadd(mm, datediff(mm, 0, getdate()) - 1, 0) END AND
DateTime < CASE WHEN day(GETDATE()) >= 20 THEN 18 + dateadd(mm, datediff(mm, 0, getdate())+ 1, 0) ELSE 18 + dateadd(mm, datediff(mm, 0, getdate()), 0) END
)

Related

Get all records by month in SQL

I am trying to pull records from a view that shows records for the next 90 days. I need a way to pull those records out by month only. I need that because not all months contain 30 days. Here is an example that shows records from today, and for the next 30 days.
select *
from [dbo].[vPolicy_Renewal_90DayLookUp] AS PRD
where PRD.ExpDate BETWEEN GETDATE() AND DATEADD(DD, 30, GETDATE())
order by PRD.ExpDate
This gets all records from today and the next 30 days but, I want a way to capture ALL records for the month. Since it's November, the previous 5 days and the rest of the month.
Here is a query for the current month:
SELECT *
FROM [dbo].[vPolicy_Renewal_90DayLookUp] AS PRD
WHERE
PRD.ExpDate >= DATEADD(mm, DATEDIFF(mm, 0, #mydate), 0) AND
PRD.ExpDate < DATEADD(mm, 1, DATEADD(mm, DATEDIFF(mm, 0, #mydate), 0));
For the second month, use this WHERE clause:
WHERE
PRD.ExpDate >= DATEADD(mm, 1, DATEADD(mm, DATEDIFF(mm, 0, #mydate), 0)) AND
PRD.ExpDate < DATEADD(mm, 2, DATEADD(mm, DATEDIFF(mm, 0, #mydate), 0));
And continue this way for the third and subsequent months. If you want just a single query for the current and next two months, then use this:
SELECT *
FROM [dbo].[vPolicy_Renewal_90DayLookUp] AS PRD
WHERE
PRD.ExpDate >= DATEADD(mm, DATEDIFF(mm, 0, #mydate), 0) AND
PRD.ExpDate < DATEADD(mm, 3, DATEADD(mm, DATEDIFF(mm, 0, #mydate), 0))
ORDER BY
PRD.ExpDate;
You should see each of the three months, in separate blocks, from earliest record to latest record.
Throwing this out as an answer, rather than a comment - this should return all rows for a given month, based on each day of "this month"
SELECT *
FROM [dbo].[vPolicy_Renewal_90DayLookUp] AS PRD
WHERE
DATEPART(MONTH,PRD.ExpDate) = DATEPART(MONTH,GetDate())
AND DATEPART(YEAR, PRD.ExpDate) = DATEPART(YEAR, GETDATE())
Add:
You may need an index on your ExpDate field, as per How to improve performance for datetime filtering in SQL Server?
#Tim Biegeleisen I found a few things with your answer. I tried using the SQL month() function but, due to earlier conversion in the DB it would never execute. That answers why #JonTout answer would not work correctly. I was able to accomplish what I wanted to by doing it this way.
DECLARE #mydate DATE, #myEndDate DATE;
SET #mydate = '12/01/2018';
SET #myEndDate = '12/31/2018';
SELECT *
FROM [dbo].[vPolicy_Renewal_90DayLookUp] AS PRD
WHERE PRD.ExpDate >= DATEADD(mm, DATEDIFF(mm, 0, #mydate), 0) AND
PRD.ExpDate < DATEADD(mm, 1, DATEADD(mm, DATEDIFF(mm, 0, #myEndDate), 0))
order by ExpDate
I am grateful for your help #Tim Biegeleisen. I found another solution to the problem I was having. This will display all records in the current month and allow me make a stored procedure for a user to choose what month they want for the next 90 days.
DECLARE #Diff Int
Set #Diff = 0
SELECT PRD.Client, PRD.ExpDate
FROM [dbo].[vPolicy_Renewal_90DayLookUp] AS PRD
where (Year(ExpDate) = YEAR(getdate()))
AND DATENAME(month, ExpDate) = DATENAME(MONTH, (Dateadd(Month, #Diff,GETDATE())))
order by ExpDate asc
I could do the same without the year() but, it works for now. I found this way to make a bit more sense to me.

SQL timestamp between hours that fall across midnight

I'm trying to find all records that would fall with in a current time period based on the current time. For example the current time is 12:30am and I need all the records from the previous day starting at 6:00pm till current time. Very new to SQL and any help would be appreciated.
Below is a screenshot of the table and the column of interest is the timestamp (datetime). I have not tried really anything concrete, am still struggling with just trying to figure out how I would go about it.
Table
The following query returns "yesterday at 6 PM":
select DATEADD(hh, -6, DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0))
The inner DATEADD gets "today at midnight" (basically just truncates the time part from "now". Try running the following by itself to see this:
select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
The outer DATEADD then subtracts 6 hours from "today at midnight" to get "yesterday at 6 PM".
So, to get all records from a table with a time greater than yesterday at 6 PM you would put this expression in a WHERE clause, like this:
select * from MyTable
where MyDateField > DATEADD(hh, -6, DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0))
The options to manipulate dates in SQL are limited only by your imagination :)
For example, in your comment below, you want to filter on "current shift", which could be 6AM-6PM or 6PM-6AM, depending on current time. This would be more complicated, but still doable, like this:
select * from MyTable
where MyDateField >=
case
when datepart(hh, getdate()) < 6 then -- if before 6AM
--yesterday at 6 PM
dateadd(hh, -6, dateadd(dd, datediff(dd, 0, getdate()), 0))
when datepart(hh, getdate()) between 6 and 18 then -- if between 6AM and 6PM
--today at 6 AM
dateadd(hh, 6, dateadd(dd, datediff(dd, 0, getdate()), 0))
else -- if after 6 PM
--today at 6 PM
dateadd(hh, 18, dateadd(dd, datediff(dd, 0, getdate()), 0))
end
and MyDateField <
case
when datepart(hh, getdate()) < 6 then -- if before 6AM
--today at 6 AM
dateadd(hh, 6, dateadd(dd, datediff(dd, 0, getdate()), 0))
when datepart(hh, getdate()) between 6 and 18 then -- if between 6AM and 6PM
--today at 6 PM
dateadd(hh, 18, dateadd(dd, datediff(dd, 0, getdate()), 0))
else -- if after 6 PM
--tomorrow at 6 AM
dateadd(hh, 30, dateadd(dd, datediff(dd, 0, getdate()), 0))
end
Notice how this reuses the same calculation for "today at midnight" and simply adds a variable number of hours to that, depending on the current hour of the day, which is where datepart comes in handy.
Good luck!
select dateadd(hour,-6,cast(cast(getdate() as date) as datetime))
This may be a bit convoluted, but the above is getting the current date and going back 6 hours. This will return 6PM from "yesterday".
You could take records where TIMESTAMP > the above.

SQL: How to get the following day from end of the month

Example:
If I run this query today (26 January), my result will be addedon +1 day which is 27 January.
select addedon
from member
Where Day(addedon) = Day(DateAdd(dd, 1, GetDate()))
and Month(addedon) = Month(DateAdd(dd, 1, GetDate()))
However, when I run this query on 31 January, it is giving me 1 January result instead of 1 Feb.
Please help! Note that I can only use simple select statement (like the above) in my application.
To get the beginning of the next month:
SELECT DATEADD(MM, DATEDIFF(MM, 0, GETDATE()) + 1, 0)
This will return member whose addedon falls on the first day of the next month.
SELECT addedon
FROM member
WHERE
addedon >= DATEADD(MM, DATEDIFF(MM, 0, GETDATE()) + 1, 0)
AND addedon < DATEADD(DD, 1, DATEADD(MM, DATEDIFF(MM, 0, GETDATE()) + 1, 0))
This will return member whose addedonfalls on the next day:
SELECT addedon
FROM #member
WHERE
addedon >= DATEADD(DD, DATEDIFF(DD, 0, GETDATE()) + 1, 0)
AND addedon < DATEADD(DD, DATEDIFF(DD, 0, GETDATE()) + 2, 0)
I'm going to guess that your datetime are - as is pretty typical - stored in your database as UTC datetime, and that you are somewhere in the Western Hemisphere, and that calling Month on a UTC time after, say, 9:30EDT (or 8:30CDT) is returning 2, matching Month(DateAdd(dd, 1, GetDate())).
Most of the time, you want to store your datetime in your database as UTC, which means - most of the time - you want to write your queries the same way (i.e., using GetUtcDate).
As a test, rewrite you query using GetUtcDate in place of GetDate, and see if your results change.

SQL - Get data based on months form a dateTime column

With SQL Server, I have a column with a launch date (dateTime). I want to report on everything that is being launched between all of last month (from viewing date) thru all of this month and next month.
So basically a full 3 month period.
What is the best way to write that?
Are you looking for something like this?
DECLARE
#StartDate DATETIME,
#EndDate DATETIME
SELECT
#StartDate = DATEADD(MM, DATEDIFF(MM, 0, GETDATE()) - 1, 0),
#EndDate = DATEADD(MM, DATEDIFF(MM, 0, GETDATE()) + 2, 0)
-- DATEADD(MM, DATEDIFF(MM, 0, GETDATE()), 0), -- beginning of this month
-- DATEADD(MM, DATEDIFF(MM, 0, GETDATE()) - 1, 0), -- beginning of last month
-- DATEADD(MM, DATEDIFF(MM, 0, GETDATE()) + 1, 0) -- beginning of next month
-- DATEADD(MM, DATEDIFF(MM, 0, GETDATE()) + 2, 0) -- beginning of two months from now
SELECT
*
FROM
[Table]
WHERE
[LaunchDate] >= #StartDate
AND [LaunchDate] < #EndDate
This will give you all the results starting from the beginning of the previous month and before the beginning of two months from now (a full 3 month range)
Maybe something like SELECT /*what_you_want*/ from launches WHERE lauchDate BETWEEN DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()) - 1, '19000101') AND DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()) + 2, '19000101')
SELECT Foo
FROM Bar
WHERE LaunchDate >= DATEADD(mm, -1, GETDATE())
AND LaunchDate <= DATEADD(mm, 1, GETDATE())

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