SQL timestamp between hours that fall across midnight - sql

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.

Related

SQL, get any data between two days and specific time

I am trying to get any data that is between that time range of two days ago until yesterday.
Example: Retrieve any data between 3 PM two days ago and yesterday 3 PM. This query should work on the daily basis.
I am thinking something like but just don't know where to insert the time
select * from dbo.table where system_date between getdate()-2 and getdate()-1
You can use CAST(CAST(GETDATE() AS date) AS datetime) to get the beginning of today's date, then use DATEADD to subtract 1 or 2 days, and add 15 hours.
I strongly suggest you use >= AND < on dates, rather than BETWEEN, otherwise you get "on the interval" issues.
SELECT t.*
FROM dbo.[table] t
WHERE t.system_date >= DATEADD(hour, 15, DATEADD(day, -2, CAST(CAST(GETDATE() AS date) AS datetime)))
AND t.system_date < DATEADD(hour, 15, DATEADD(day, -1, CAST(CAST(GETDATE() AS date) AS datetime)));
try this
select *
from dbo.table
where system_date between dateadd(day, datediff(day, 2, getdate()), '15:00:00') and dateadd(day, datediff(day, 1, getdate()), '15:00:00')
You should use DATEADD for subtracting dates. Your query will look like this.
select *
from table
where system_date between dateadd(day, -2, getdate()) and dateadd(day, -1, getdate())

How to pull the past two years of data, but not the data in the current month in SQL

I am trying to pull the data from the past two years, starting from the the past month (not taking into account the current month).
So it will pull all 2 years of data starting from 09/30/2021.
I've tried the following, but the months after September for 2020 get taken out:
WHERE YEAR(ACCDAT_0) >= (YEAR(GETDATE()) -2) AND MONTH(ACCDAT_0) < MONTH(dateadd(dd, -1, GetDate()))
DECLARE #d date = GETDATE();
SET #d = DATEFROMPARTS(YEAR(#d), MONTH(#d), 1);
SELECT ... WHERE ACCDAT_0 >= DATEADD(YEAR, -2, #d)
AND ACCDAT_0 < #d;
Several helpful date articles here, including why you want range queries and not things like YEAR(column): Dating Responsibly
You may try the following logic:
SELECT *
FROM yourTable
WHERE ACCDAT_0 >= DATEADD(year, -2, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0)) AND
ACCDAT_0 < DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0);

Using DATEADD and DATEDIFF truncates the time

I am using the following to get to get the 1st day of next month with time:
select DATEADD(m, DATEDIFF(m, -1, getdate()), 0)
But the output is:
2018-12-01 00:00:00.000
And the expected result is:
2018-12-01 11:53:30.677
I have tried various approaches but not able to get required output. I am using SQL Server 2008.
You can add two datetime values, one for the date and the other for the time:
select DATEADD(month, DATEDIFF(month, -1, getdate()), 0) + cast(cast(getdate() as time) as datetime)
I am guessing that you want the time value from the current time.
Subtract DAY(#date) - 1 days from #date to get first day of that month including time. Then add one month:
SELECT DATEADD(MONTH, 1, DATEADD(DAY, -DAY(GETDATE()) + 1, GETDATE()))
-- 2018-12-01 04:52:33.403
try like below
select DATEADD(m, DATEDIFF(m, -1, getdate()), 0)+ convert(DATETIME,'11:53:30.677')
in case of current time it would be like below
select DATEADD(m, DATEDIFF(m, -1, getdate()), 0)+ convert(datetime, convert(time,getdate()))

Last 5 weeks prior to the last week in SQL

I want to take the last 5 weeks prior to the week before the current week. Today is Oct 4, 2017 so I want date range to be between Aug 21-Sep 24. This is the code I'm using, but it doesn't work for some reason:
DATEADD(week, -5, GETDATE()) and DATEADD(week, -1, GETDATE())
I also tried DATEADD(week, -6, GETDATE()) and DATEADD(week, -2, GETDATE()) but no change happens, so weird.
Can anyone help me please. It's sql query in SQL 2012.
WHERE hire_date between DATEADD(week, -6, GETDATE()) and DATEADD(week, -2, GETDATE())
Look at each of the expressions individually. Use Management Studio (or similar) to run just this:
SELECT DATEADD(week, -1, GETDATE())
And you'll see something like this (relative to the time when you run it):
2017-09-27 15:05:39.453
That's exactly one week ago, which was still a Wednesday. You want Sunday, the start of that week. So now do this:
SELECT DATEADD(week, DATEDIFF(week, 0, GETDATE()) -1, 0)
Which gives you this result:
2017-09-25 00:00:00.000
Closer. It works by taking day 0 and adding one less than the number of weeks that have passed since the week from your target date. You're adding whole weeks, and so you end up with a predictable whole-week start. You get the 25th (Monday) instead of the 24th because day 0 (Jan 1 1900) happened to be a Monday. But it's reliably a Monday, and easy enough now to account for the one more day:
SELECT DATEADD(DAY, -1, DATEADD(week, DATEDIFF(week, 0, GETDATE()) -1, 0))
And now we have a date you can use, from an expression that will consistently get it right:
2017-09-24 00:00:00.000
Sort of. You do need to carefully test how this behaves if run on Sunday or Monday, especially as Sql Server has a configurable start-of-week value. You may find you've crossed one fewer or greater week boundaries than you expect and end up with weird off-by-one errors. But even if that happens, this approach puts you on the path you need to walk.
For the other end, just change the number of weeks:
SELECT DATEADD(week, DATEDIFF(week, 0, GETDATE()) -6, 0)
To get this:
2017-08-21 00:00:00.000
Since the question asked for the Monday instead of Sunday we get skip the extra DATEADD() from before.
Now put it all together like so:
WHERE hire_date between
DATEADD(week, DATEDIFF(week, 0, GETDATE()) -6, 0)
AND
DATEADD(DAY, -1, DATEADD(week, DATEDIFF(week, 0, GETDATE()) -1, 0))
From what you're saying I think you need the first day of the earliest week to the last day of the latest week. To achieve this, you can do this:
WHERE hire_date between DATEADD(week, -6, DATEADD(WEEK, DATEDIFF(wk,0,GETDATE()), 0))
and DATEADD(week, -2, DATEADD(WEEK, DATEDIFF(wk,5,GETDATE()), 6))
DATEADD(week, -5, GETDATE()) substracts 30 days. You are going to have to do some manual DATEADD to get it to the beginning of the week, which is what it sounds like you're trying to do.
DECLARE #date datetime = GETDATE()
DECLARE #dw nvarchar = DATENAME(dw, #date)
IF #dw = 'Monday' SET #date = DATEADD(day, -1, #date)
ELSE IF #dw = 'Tuesday' SET #date = DATEADD(day, -2, #date)
....
WHERE hire_date between DATEADD(week, -6, #date) and DATEADD(week, -2, #date)
This way, you can set the beginning of the week yourself without having to be dependent on system culture.

SQL Server get records before a defined time

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.