WHERE date BETWEEN today and next 30 days not working - sql

I'm having a bit of trouble with pulling records which are due within 30 days. The database I am working with stores the date in a char(10) field in format 103 (dd/mm/yyyy or 10/12/2021). I use a convert function to make this date usable, but when I try to use it with a between query it fails:
WHERE
CONVERT(Date, SUBSTRING(TDate, 1, 10), 103)
BETWEEN DATEADD(DAY, 30, GETDATE()) AND GETDATE()
Now I suspect that it fails because GETDATE() defaults to format yyyy-mm-dd-time, so the comparison won't work. My question is, how can I convert GETDATE() to format 103 to get the correct comparison, or is it a matter of converting my TDate field to something else to get it working?

The expression x BETWEEN a AND b is same as x >= a AND x <= b.
Now GETDATE() + 30 is always going to be greater than GETDATE() so this condition can never be true for any value — just like x >= (y + 30) and x <= y cannot be true for any x and y.
Then we have another problem, you're comparing a date with datetime. If the date is 2021-12-10 and current datetime is 2021-12-10 12:00 PM then the comparison will return false when you check date >= datetime. I recommend the following:
WHERE CONVERT(DATE, tdate, 103) >= CAST(GETDATE() AS DATE)
AND CONVERT(DATE, tdate, 103) <= DATEADD(DAY, 29, CAST(GETDATE() AS DATE)) -- the range [0, 29] contains 30 days

Related

How to create a time of 9pm today in SQL

I am trying to get a smalldatetime value of "9pm today" in a query. I thought I could use
DATEADD(HOUR, 21, CONVERT(date, GETDATE()))
but SQL Server doesn't like that - I get the error
The datepart hour is not supported by date function dateadd for data
type date.
Suggestions for a workaround?
Pretty simple, just cast date back to datetime after casting to date.
Thus you'll get current_date 00:00:00 and then add 21 hours:
select dateadd(hh, 21, cast(cast(getdate() as date) as datetime))
it is because dateadd's 3rd parameter should be datetime type, not date.
SELECT DATEADD(HOUR, 21, CONVERT(datetime,CONVERT(date, GETDATE())))
just add 21 / 24.0 to todays date
Select dateadd(day, datediff(day, 1, getDate()), 1) + (21 / 24.0)
First part, dateadd(day, datediff(day, 1, getDate()), 1), strips time from getdate(),
second part, + (21 / 24.0), adds fractional part of day equal to 9 am
This works because internally, SQL Server represents datetimes as two integers, one for the date, (number of days since 1 Jan 1900), and a second integer for the time, (number of ticks since midnight), which it combines into a decimal value where the integer part is the date integer, and the decimal part is the fraction of one day, so if you add 0.5 to a date, you get noon on that day, etc.
or, for comparison, using dateadd for hours,
Select dateadd(hour, 21, dateadd(day, datediff(day, 1, getDate()), 1))

SQL Query for 1 hour data using the datetime format YYYYMMDDHHMMSS

How to query for 1 hour data, my date-time format is YYYYDDMMHHMMSS?
example:
20120720094318
20120720121318
20120720144028
Tried finding the query online still doesn't work.
Tried:
enddate >= FORMAT(DATEADD(dd,-1,GETDATE()), 'yyyyMMdd000000')
I would like something like this:-
Sample data:
Cup machine end date
123 BB1 20120720092318
333 BB1 20120720094418
444 BB1 20120720084218
555 BB1 20120720082318
if i run the query # 10am on above sample data i should have
Cup machine end date
123 BB1 20120720092318
333 BB1 20120720094418
which means to get record between 9am - 10am
Try it like this (working in SQL-Server):
This converts your date to "real" date-time datatype.
You might do this with alphanumeric values, but I wouldn't...
DECLARE #tbl TABLE(Cup INT,machine VARCHAR(100),[end] VARCHAR(100));
INSERT INTO #tbl VALUES
(123,'BB1','20120720092318')
,(333,'BB1','20120720094418')
,(444,'BB1','20120720084218')
,(555,'BB1','20120720082318');
;WITH Converted AS
(
SELECT Cup,machine,[end]
,CONVERT(DATETIME,STUFF(STUFF(STUFF([end],9,0,' '),12,0,':'),15,0,':')) AS EndConverted
FROM #tbl
)
SELECT *
FROM Converted
WHERE EndConverted BETWEEN {ts'2012-07-20 09:00:00'} AND {ts'2012-07-20 10:00:00'}
The result
Cup machine end EndConverted
123 BB1 20120720092318 2012-07-20 09:23:18.000
333 BB1 20120720094418 2012-07-20 09:44:18.000
This is an effective/efficient way to truncate getdate() to just the current day, it gets the numbers of days since the calendar 0 reference date (1900-01-01), then it adds that number of days to the 0 reference date.
dateadd(day, datediff(day,0, getdate() ), 0)
then add the current hour to that using hour(getdate())
dateadd(hour,hour(getdate()),dateadd(day, datediff(day,0, getdate() ), 0))
so we arrive at the starting point of the range. To get the other end of the range, just add 1 more hour like so:
dateadd(hour,hour(getdate())+1,dateadd(day, datediff(day,0, getdate() ), 0))
then:
enddate >= FORMAT(dateadd(hour,hour(getdate()),dateadd(day, datediff(day,0, getdate() ), 0)), 'yyyyMMdd000000')
and enddate < FORMAT(dateadd(hour,hour(getdate())+1,dateadd(day, datediff(day,0, getdate() ), 0)), 'yyyyMMdd000000')
If it turns out your enddate column is a true datetime column, do NOT use the format() function because you can directly compare a datetime column to the calculated datetime value we have derived from getdate()
i.e. dateadd() returns a datetime
enddate >= dateadd(hour,hour(getdate()),dateadd(day, datediff(day,0, getdate() ), 0))
and enddate < dateadd(hour,hour(getdate())+1,dateadd(day, datediff(day,0, getdate() ), 0))
note: I don't use or recommend using between for date ranges, use the combination >= with < instead.
To truncate getdate() an alternative approach is to use cast(getdate() as date) and with that as the basis you could use:
enddate >= FORMAT(dateadd(hour,hour(getdate()), cast(getdate() as date)), 'yyyyMMdd000000')
and enddate < FORMAT(dateadd(hour,hour(getdate())+1, cast(getdate() as date)), 'yyyyMMdd000000')
or, if not a varchar column but datetime:
enddate >= dateadd(hour,hour(getdate()), cast(getdate() as date))
and enddate < dateadd(hour,hour(getdate())+1, cast(getdate() as date))

Today Production - SQL Date Calculation case when

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

SQL Greater than specific time on the previous day

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().

how can I get last 7 days of data being my date field a number?

I need to get last 7 days data excluding Sunday being my date field a number. How can I do it? Field structure 20140425. For example is I run the statement today it should give me date range between 20140424 - 20140417 excluding 20140420.
The hitch is of course converting the number based date to a real date. This seems to work:
select convert(datetime, convert(char(10), 20140425))
To expand, your query would look like this:
select *
from [Table]
where convert(datetime, convert(char(10), [columnname])) between convert(varchar, getdate() - 8, 101) and convert(varchar, getdate() - 1, 101)
and datepart(DW, convert(datetime, convert(char(10), [columnname]))) <> 1
The convert(varchar, getdate - 1, 101) will return you 12:00am yesterday morning. My first pass didn't include that and would've only given a 6 day range.
SELECT *
FROM Table_Name
WHERE CAST(DateField AS DATE) >= DATEADD(DAY, -7, GETDATE())
AND CAST(DateField AS DATE) <= GETDATE()
AND DATEPART(DW,CAST(DateField AS DATE)) <> 1