SQL Server get records before a defined time - sql

I am trying to get a list of records that have been in the system only before 05:00:00 pm of the day the query is being run. I have this query that works in the basic testing, but I wanted to see if there is a better option than to do the SQL concatenation.
select *
from Payment
where createTimestamp <= CONVERT(VARCHAR(10), Getdate(), 120) +' '+'17:00:00';
This query will be used on SQL Server 2008.

Select ...
From Payment
Where CreateTimeStamp <= DateAdd(hh, 17, DateDiff(d, 0, CURRENT_TIMESTAMP))
Another option given that you are using SQL Server 2008
Select ...
From Payment
Where CreateTimeStamp <= DateAdd(hh, 17, Cast(Cast(CURRENT_TIMESTAMP As Date) As DateTime))

This will retrieve all records with a createTimestamp between 12am and 5pm today.
select *
from Payment
where createTimestamp
between dateadd(dd, datediff(dd, 0, getdate()), 0)
and dateadd(hh, 17, dateadd(dd, datediff(dd, 0, getdate()), 0))
This will retrieve all records with a createTimestamp between 5pm yesterday and 5pm today.
select *
from Payment
where createTimestamp
between dateadd(hh, -7, dateadd(dd, datediff(dd, 0, getdate()), 0))
and dateadd(hh, 17, dateadd(dd, datediff(dd, 0, getdate()), 0))
For more fun with sql dates check out my answer to GETDATE last month.

Related

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 query to select range from specific date/time yesterday to specific date/time current day

SELECT *
FROM services
WHERE service_date BETWEEN (dateadd(DD, -1, getdate())) AND (dateadd(DD, 1, getdate())) **---Gives us a last one day data.**
but what we really need is data from 07:00 AM yesterday to 06:59 AM current day, so I tried the following:
SELECT *
FROM services
WHERE service_date BETWEEN (dateadd(DD, -1,((DatePart(hh, getdate())) >= 7 ))) **-- Expecting to pull from yesterday 07:00**
AND (dateadd(DD, -1,((DatePart(hh, getdate())) <= 6 ))) **-- to current day till 06:59**
but the system didn't like my SQL skills ...PLEASE HELP...!
These will get you the dates you are looking for...
Select DATEADD(HOUR,-17, (DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)))
Select DATEADD(HOUR,7, (DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)))
I'm not sure if this is the most effective way but it works.
Assuming you are on SQL Server:
Select *
From MyTable
Where MyDateColumn Between DATEADD(hh, 7, Cast(Cast(DATEADD(d, -1, CURRENT_TIMESTAMP) As Date) As DateTime))
And DATEADD(hh, 6, Cast(Cast(CURRENT_TIMESTAMP As Date) As DateTime))
UPDATE: I agree with Andy's solution. Similar approach but his solution is much more elegant and efficient.
Try something like that:
SELECT *
FROM services
WHERE service_date
BETWEEN Convert(DateTime, Convert(nchar(4), DatePart(YYYY, GETDATE())) + '-'
+ Convert(nchar(2), DATEPART(MM, GETDATE())) + '-'
+ Convert(nchar(2), DATEPART(DD, Getdate())-1) + ' 7:00:00')
AND Convert(DateTime, Convert(nchar(4), DatePart(YYYY, GETDATE())) + '-'
+ Convert(nchar(2), DATEPART(MM, GETDATE())) + '-'
+ Convert(nchar(2), DATEPART(DD, Getdate())) + ' 6:59:00')
The idea is to take the year, month and day from today (or yesterday), and form a new date by concatenate them.
Beware of the culture settings for date format and do some testing before put this code into production.
You could also use mi (minutes) with DateAdd. Adding 419 minutes to midnight to get 06:59 and a nice round 420 minutes to yesterday midnight for 07:00
Edit: Changed the DateDiff function to work with Sybase.
SELECT *
FROM services
WHERE service_date BETWEEN DATEADD(mi, 420, DATEADD(d, -1, DATEDIFF(d, DATE('1900-01-01'), GETDATE())))
AND DATEADD(mi, 419, DATEADD(d, -0, DATEDIFF(d, DATE('1900-01-01'), GETDATE())));
Edit: Removing DateDiff function
SELECT *
FROM services
WHERE service_date BETWEEN DATEADD(mi, 420, DATEADD(d, - 1, Convert(VARCHAR(10), GETDATE(), 111)))
AND DATEADD(mi, 419, DATEADD(d, - 0, Convert(VARCHAR(10), GETDATE(), 111)));

First business day of the current month - SQL Server

How could I get the first business day of the current month?
Without create a function, only select.
something like that:
SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(GETDATE())-1), GETDATE()), 101)
somebody knows please?
Thanks.
A Simple case statement could do it
SELECT CASE
WHEN DATENAME(WEEKDAY, dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)) = 'Saturday'
THEN dateadd(mm, DATEDIFF(MM, 0, getdate()), 0) + 2
WHEN DATENAME(WEEKDAY, dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)) = 'Sunday'
THEN dateadd(mm, DATEDIFF(MM, 0, getdate()), 0) + 1
ELSE dateadd(mm, DATEDIFF(MM, 0, getdate()), 0)
END
This will literally give you what you're asking for -- the first business day in a month if we define a business day as "any day that's not a Saturday or a Sunday". But this is is a very narrow definition of "business day" that is not appropriate when taking into account holidays and cultural differences, so it generalizes poorly. The typical solution for this problem is to create a table that actually holds the working days (which is generated somewhere just before he year, or calculated in advance if that's feasible), and simply look it up in that.
SELECT DATEADD(DAY,
CASE
(DATEPART(WEEKDAY, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)) + ##DATEFIRST - 1) % 7
WHEN 6 THEN 2
WHEN 7 THEN 1
ELSE 0
END,
DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)
)
This solution uses ##DATEFIRST to avoid any language issues -- using DATEPART(WEEKDAY, ...) on its own or DATENAME() only works if we assume a specific region.
If you have more flexibility in your SELECT statement, you might be able to use something like this:
;With Daterange As
(
Select DateAdd(Month, DateDiff(Month, 0, GetDate()), 0) As Date Union All
Select DateAdd(Day, 1, Date) As Date
From DateRange
Where Date < DateAdd(Day, 6, DateAdd(Month, DateDiff(Month, 0, GetDate()), 0))
)
Select Convert(Date, Min(Date)) FirstBusinessDay
From Daterange
Where DatePart(WeekDay, Date) Not In (7, 1)
Try this.
SELECT CASE
WHEN Datename(dw, Dateadd(dd, -Datepart(dd, Getdate()) + 1, Getdate())) = 'Saturday' THEN Dateadd(dd, -Datepart(dd, Getdate()) + 3, Getdate())
WHEN Datename(dw, Dateadd(dd, -Datepart(dd, Getdate()) + 1, Getdate())) = 'Sunday' THEN Dateadd(dd, -Datepart(dd, Getdate()) + 2, Getdate())
ELSE Dateadd(dd, -Datepart(dd, Getdate()) + 1, Getdate())
END
Explanation :
Find the first day of the month.
Dateadd(dd, -Datepart(dd, Getdate()) + 1, Getdate())
Then check the day of the previous date by using Datename function.
Datename(dw, Dateadd(dd, -Datepart(dd, Getdate()) + 1, Getdate()))
If the Datename is Saturday the add 2 days to the first day of the month . if it is sunday then add 1 day to the first day of the month else get the first day of the month

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