A shift in our plant is defined as starting at 4am and continues until 2 am on the following day.
At 3 am on a given day I want to get all the records for the previous shift.
The query below gets me the previous day upto now but also includes 12am to 2 am on the "previous previous" shift. How do i get the query to get data ONLY after 4am ?
select
*
from yourTable
WHERE TimeStamp >= dateadd(day,datediff(day,1,GETDATE()),0)
DECLARE #yesterday DATE = GETDATE()-1
DECLARE #time TIME = '04:00:00'
DECLARE #shiftstart DATETIME = CAST(#yesterday AS DATETIME) + CAST(#time AS DATETIME)
select
*
from yourTable
WHERE TimeStamp >= #shiftstart
The logic is to subtract 2 hours from the shift time and use the date portion. A simplistic implementation is:
where cast(dateadd(hour, -2, TimeStamp) as date) = cast(dateadd(day, -1, GetDate()) as date)
Sometimes, it is more efficient to do all the arithmetic on the "constant" (i.e. getdate()):
where TimeStamp >= dateadd(hour, 2, cast(GetDate() as Date))
Note: the appropriate function for this logic is dateadd() not datediff().
Related
I have a query -
SELECT * FROM TABLE WHERE Date >= DATEADD (day, -7, -getdate()) AND Date <= getdate();
This would return all records for each day except day 7. If I ran this query on a Sunday at 17:00 it would only produce results going back to Monday 17:00. How could I include results from Monday 08:00.
Try it like this:
SELECT *
FROM SomeWhere
WHERE [Date] > DATEADD(HOUR,8,DATEADD(DAY, -7, CAST(CAST(GETDATE() AS DATE) AS DATETIME))) --7 days back, 8 o'clock
AND [Date] <= GETDATE(); --now
That's because you are comparing date+time, not only date.
If you want to include all days, you can trunc the time-portion from getdate(): you can accomplish that with a conversion to date:
SELECT * FROM TABLE
WHERE Date >= DATEADD (day, -7, -convert(date, getdate())
AND Date <= convert(date, getdate());
If you want to start from 8 in the morning, the best is to add again 8 hours to getdate.
declare #t datetime = dateadd(HH, 8, convert(datetime, convert(date, getdate())))
SELECT * FROM TABLE
WHERE Date >= DATEADD (day, -7, -#t) AND Date <= #t;
NOTE: with the conversion convert(date, getdate()) you get a datatype date and you cannot add hours directly to it; you must re-convert it to datetime.
Sounds like you want to remove the time. Correct? If so then do the following.
SELECT * FROM TABLE WHERE Date >= (DATEADD (day, -7, -getdate()) AND Date DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0))
I have an issue regarding date calculations.
I have a datetime column called CreatedLocalTime date with this format: 2015-11-15 19:48:50.000
I need to retrieve a new column called Prod_Date with:
if “CreatedLocalTime” between
(CreatedLocalTime 7 AM)
& (CreatedLocalTime+1 7 AM)
return CreatedLocalTime date with DD/MM/YYYY format
On other words, today production = sum of yesterday from 7 AM till today at 7 AM.
Any help using case?
For day 7AM to day+1 7AM, you can try:
SELECT CAST(CreatedLocalTime as date)
...
FROM ...
WHERE ...
CreatedLocalTime >= DATEADD(hour, 7, CAST(CAST(CreatedLocalTime as date) as datetime))
AND
CreatedLocalTime < DATEADD(hour, 31, CAST(CAST(CreatedLocalTime as date) as datetime))
...
For previous day 7AM to day 7AM, replace 7 by -14 and 31 by 7.
Another way..
SELECT CASE WHEN CreatedLocalTime BETWEEN DATEADD(HOUR, 7,
CAST(CAST (CreatedLocalTime AS DATE) AS DATETIME))
AND DATEADD(HOUR, 31,
CAST(CAST (CreatedLocalTime AS DATE) AS DATETIME))
THEN REPLACE(CONVERT(NVARCHAR, CreatedLocalTime, 103), ' ', '/')
END AS CreatedLocalTime
You can write the else part for this, if needed
It looks like you want somthing along the lines of
DECLARE #StartDateTime Datetime
DECLARE #EndDateTime Datetime
SET #EndDateTime = DATEADD(hour, 7,convert(datetime,convert(date,getdate())) )
SET #StartDateTime = DATEADD(day, -1, #EndDateTime )
--Print out the variables for demonstration purposes
PRINT '#StartDateTime = '+CONVERT(nchar(19), #StartDateTime,120)
PRINT '#EndDateTime = '+CONVERT(nchar(19), #EndDateTime,120)
SELECT SUM (Production) AS Prod_Date FROM YourSchema.YourTable WHERE CreatedLocalTime >= #StartDateTime AND CreatedLocalTime < #EndDateTime
But you could also look at it as all the times which after you remove 7 hours from them are yesterday
SELECT SUM (Production) AS Prod_Date
FROM YourSchema.YourTable
WHERE DATEDIFF(day,DATEADD(hour, -7, CreatedLocalTime ))) = 1
The First version will be more efficient as the query will only have to do the date arithmetic once at the start while the second involved executing DATEDIFF and DATEADD for every record. This will be slower on large amounts of data.
The Gold plated solution would be to add a computed column to your table
ALTER TABLE YourSchema.YourTable ADD EffectiveDate AS CONVERT(date, DATEDIFF(day,DATEADD(hour, -7, CreatedLocalTime ))))
And then an index on that column
CREATE INDEX IX_YourTable_EffectiveDate ON YourSchema.YourTable (EffectiveDate )
So you can write
DECLARE #YesterDay date = DATEADD(day,-1, getdate())
SELECT SUM (Production) AS Prod_Date
FROM YourSchema.YourTable
WHERE EffectiveDate = #YesterDay
Could you help me with this please.
I would like to get the records only if the DATEDIFF(day, due_date, GETDATE()) is more than 60 but is less than 90 days (or between 60 days and 90 days). If it is lesser than 60 or greater than 90 days, then leave it out).
Thank you!
a sargable alternative =>> it does not use functions on the data
-- DECLARE #today datetime = CAST(GETDATE() AS date) -- an option
DECLARE #today datetime = DATEADD(DAY, DATEDIFF(DAY,0, GETDATE()), 0)
SELECT
due_date
FROM some_table
WHERE (
due_date >= DATEDIFF(DAY, -90, #today)
AND due_date < DATEDIFF(DAY, -60, #today)
)
GETDATE() returns both date and the current time, so to get "today" at 00:00:00 you need to either cast getdate to a date, or use the dateadd function as shown above.
Then instead of calculating the days different for each row of data (2 functions for each row) and filtering on that calculated column (this could require hundreds, thousands or millions of calculations), why not compare the existing data to 2 calculated dates?
See: Sargable
Try this:
declare #today smalldatetime = getdate()
select
due_date
from
some_table
where
datediff(day, due_date, #today) > 60 and
datediff(day, due_date, #today) < 90
I come in to work 6.30am, and need to audit what happened from 5pm when I left to 6.30am this morning. I have used code to search 13.5 hours back from any given time:
SELECT * FROM TRANSACTION_HISTORY
WHERE TRANSACTION_HISTORY.ACTIVITY_DATE_TIME > (SELECT DATEADD(hour,-13.5,(SELECT MAX (TRANSACTION_HISTORY.ACTIVITY_DATE_TIME) FROM TRANSACTION_HISTORY)))
Problem is if I run query later, I lose time from the start, eg. If I run query at 7am, I only get results from 5.30pm onwards. Rather than change criteria every day, I wanted to able to search from 6.30am of the current day, back to 5.30pm of the previous day. Can this be done?
Normally, I don't advise using between for datetime, because the boundary conditions can cause confusion. I don't think that is the case.
Here is one method:
SELECT *
FROM TRANSACTION_HISTORY th
WHERE th.ACTIVITY_DATE_TIME between cast(cast(getdate() -1 as date) as datetime) + 17.5/24.0
cast(cast(getdate() as date) as datetime) + 6.5/24.0;
The expression cast(cast(getdate() as date) as datetime) is truncating the datetime value to midnight. As a datetime, SQL Server lets you add a number which is understood as a fraction of a day. Hence, 17.5/24 represents "5:30". This addition doesn't work for the date data type.
You can do this.
DECLARE #dt datetime
DECLARE #dt1 datetime
DECLARE #dt2 datetime
SET #dt = CONVERT(datetime, CONVERT(VARCHAR(10), getdate(), 101 ), 101)
SET #dt1 = dateadd(mi, 30, dateadd(hh, 6, #dt))
SET #dt2 = dateadd(mi, -27*30, #dt1)
SELECT #dt1 as StartDate, #dt2 as EndDate
For additional details what this script does you may check these pages.
http://technet.microsoft.com/en-us/library/ms174450%28v=sql.105%29.aspx
http://technet.microsoft.com/en-us/library/ms186819%28v=sql.105%29.aspx
I'm trying to select records that were added to the database between the start of the current month and the current day - I more or less know how to get records from the current day, and within a specific time period - but how do I get it so it starts from the beginning of the current calendar month?
DECLARE #sm DATETIME;
SET #sm = DATEADD(DAY, 1-DAY(GETDATE()), DATEDIFF(DAY, 0, GETDATE()));
SELECT columns
FROM dbo.foo
WHERE datetime_column >= #sm;
WHERE YEAR([Date])=YEAR(GETDATE())
AND MONTH([Date])=MONTH(GETDATE())
AND DAY([Date])<=DAY(GETDATE())
select *
from YourTable
where DateCol >= dateadd(month, datediff(month, 0, getdate()), 0)
Basically what you're doing here is Getting the Month, appending '/01' and then appending the year. Casting it as a string to handle the appending, then casting it as a DateTime.
So it's a little bit more involved than doing any sort of date math, but it's readable I think.
DECLARE #firstOfMonth DATETIME
SET #firstOfMonth = CAST(CAST(DATEPART(mm, GetDate()) as varchar) + '/01/' + cast(DATEPART(yyyy, Getdate()) as varchar) as datetime)
WHERE DateToCheck BETWEEN #firstOfMonth and GetDate()
WHERE DateToCheck > LAST_DAY(CURDATE()-INTERVAL 1 MONTH))
http://www.sqlfiddle.com/#!2/3d673/2/0