TSQL DateTime Comparison - tsql

What I am trying to do is get a result from sql where the dates are in a certain range but its not working correctly, here is my query.
DECLARE #CurrDate DATETIME
SET #CurrDate = GETDATE()
SELECT dbo.ProductDetails.PartnerID
,dbo.ProductDetails.ProductID
,dbo.Products.ProductName
,StartDate
,EndDate
FROM dbo.ProductDetails
INNER JOIN dbo.Products
ON dbo.ProductDetails.ProductID = dbo.Products.ProductID
WHERE CONVERT(VARCHAR(10),StartDate,111) <= #CurrDate
AND CONVERT(VARCHAR(10),EndDate, 111) >= #CurrDate
but when the Enddate = #CurrDate the row does not show, but if i make that date just one day higher it gets displayed. Am i doing anything wrong? Any advice will do, thanks.

GetDate() returns date and time, while your conversion to varchar strips away the time part (I'm suspecting that's all it's actually supposed to do). So you would need to do the same conversion for #CurrDate.
If what you want is to simply consider the date only (ignoring the time part), you could use DATEDIFF instead of converting to varchar (see here); example:
DECLARE #CurrDate DATETIME
SET #CurrDate = GETDATE()
SELECT dbo.ProductDetails.PartnerID, dbo.ProductDetails.ProductID,
dbo.Products.ProductName , StartDate, EndDate
FROM dbo.ProductDetails INNER JOIN
dbo.Products ON dbo.ProductDetails.ProductID = dbo.Products.ProductID
-- where StartDate is on the same day or before CurrDate:
WHERE DATEDIFF(day, StartDate, #CurrDate) >= 0 AND
-- and where EndDate is on the same day or after CurrDate:
DATEDIFF(day, EndDate, #CurrDate) <= 0

If you want only DATE comparison, without time use the
cast(CONVERT(varchar, StartDate, 112) as datetime)

I am quite sure that the comparison takes into account the time as well as the date, in which case if the dates are the same but the current time is greater than the time being compared to you won't get that row as a result.
So, what you need to do is just extract the date part and compare those.

GETDATE() gives you date and time
if yours column have only date
then
CONVERT(VARCHAR(10),StartDate,111) <= #CurrDate
can give you unexpected result
remember
19.12.2011 14:41 > 19.12.2011 00:00

If you are using SQL 2008 or later, and wanting to compare only the date, not the time, you can also do:
Cast(StartDate as Date)
(This avoids having to convert to a string.)

Related

sqlite date comparison

I have column of type date time and values are getting stored in format 10-29-2011 08:25.
I would like to find out the rows only which are less then current date-time. What will be the condition for date comparison for current date and this date-time column field?
Thanks.
you could use the datetime function
SELECT * FROM mytable
WHERE mydate > datetime('now')
you can even make date operations
SELECT * FROM mytable
WHERE mydate > datetime('now','-15 days')

SQL SERVER passing getdate() or string date not working correctly

CREATE PROCEDURE sp_ME
#ID int,
#ThisDate datetime = null
AS
SET NOCOUNT ON
IF #ThisDate IS NULL
BEGIN
SET #ThisDate = CURRENT_TIMESTAMP
END
DECLARE #intErrorCode int,
#QBegin datetime,
#QEnd datetime
SELECT #intErrorCode = ##ERROR
IF #ThisDate BETWEEN '01/01/' + CONVERT(VARCHAR(4), YEAR(#ThisDate))
AND '03/31/' + CONVERT(VARCHAR(4), YEAR(#ThisDate))
BEGIN
Select #QBegin = DATEADD(s,0,CAST ('10/01/' AS varchar(6) ) +
CONVERT(VARCHAR(4),DATEPART (year,#ThisDate)-1))
Select #QEnd = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#QBegin)+3,0))
SELECT * FROM QUERY
WHERE MEID = #ID
AND mydate >= #QBegin
AND mydate <= #QEnd)
END
SELECT #intErrorCode = ##ERROR
IF (#intErrorCode <> 0) GOTO ErrHandler
ErrHandler:
RETURN #intErrorCode
GO
It returns a dataset when you leave it blank and it assumes and fills in the date, however when you plug in a date it just states "The command completed successfully."
Any help would be more than appreciated.
At a guess, you need to query the previous quarter's results, which would just be this query:
SELECT * FROM QUERY
WHERE MEID = #ID
AND mydate >= DATEADD(quarter,DATEDIFF(quarter,'20010101',#ThisDate),'20001001'),
AND mydate < DATEADD(quarter,DATEDIFF(quarter,'20010101',#ThisDate),'20010101'))
And get rid of that big if condition, etc.
You could also get rid of the first if, if you put COALESCE(#ThisDate,CURRENT_TIMESTAMP) in the above, where I currently have #ThisDate.
I use the DATEADD(quarter,DATEDIFF(quarter,'20010101',#ThisDate),'20001001') pattern for a lot of datetime manipulation. It let's you achieve a lot in a few operations. In this case, it's the difference between the two dates ('20010101','20001001') which is giving us the previous quarter.
You'll frequently encounter the DATEADD/DATEDIFF pattern in questions involving removing the time portion from a datetime value. The canonical version of this is DATEADD(day,DATEDIFF(day,0,#Date),0). But the pattern can be generally extended to work with any of the datetime components. If you choose month rather than day, you'll get midnight at the start of the first of the month (of the day you've supplied)
Where it gets tricky is when you use dates (instead of 0), and especially if you don't use the same date for both calculations. This allows you to apply an additional offset that seems almost "free" - you're already using this construct to remove the time component, the fact that you can compute e.g. the last date in a quarter/month/etc is a bonus.

T-SQL How to update hour in a SmallDateTime column?

let's say that I have a SmallDateTime column in my table. How to update hours in each row in T-SQL ?
Get the target value's hour part.
Find the difference between the hour you want and the found hour.
Add the difference of hours to the target value.
The script:
UPDATE atable
SET datetimevalue = DATEADD(hour, #hour - DATEPART(hour, datetimevalue),
datetimevalue)
WHERE ...
UPDATE YourTable SET YourDateColumn = DateAdd(hh, 1, YourDateColumn)
will add 1 hour to the time value in YourDateColumn in every single row.
See this page for more info.
UPDATE YourTableName
SET YourSmallDateTimeColumn = DATEADD(HH, 1, YourSmallDateTimeColumn)
Will add any number of hours to your column. So if you get rid of the time component first:
SELECT CAST(CONVERT(char(8), YourSmallDateTimeColumn, 112) AS smalldatetime)
and add hour component to it later it should work.
From here
To add or subtract hours to a datetime
or smalldatetime value, you will use
the DATEADD date function. The
DATEADD date function returns a new
datetime value based on adding an
interval to the specified date. The
syntax of the DATEADD date function is
as follows:
DATEADD ( datepart , number, date )
datepart is the parameter that
specifies on which part of the date to
return a new value. For hours, you
can use either HOUR or HH. number is
the value used to increment datepart.
date is an expression that returns a
datetime or smalldatetime value, or a
character string in a date format.
Here's an example on how to use the
DATEADD date function to increase or
decrease a datetime value by a certain
number of hours:
SELECT DATEADD(HOUR, -12, GETDATE())AS [TwelveHoursAgo]
SELECT DATEADD(HH, 6, GETDATE()) AS [SixHoursLater]

in sql between #startdate and #enddate does not compare time part ? How to compare time parts of date

I have query like this
SELECT AVAILABILITY_DATE_TIME FROM APPT_PROVIDER_AVAILABILITY
WHERE AVAILABILITY_DATE_TIME between #START_DATE AND #END_DATE
suppose i have
if #startdate = '2/11/2010 11:31:00 AM' and #enddate = '2/11/2010 11:56:00 AM'
then difference is zero its ignoring time part .
If you can provide query plz use
table name : APPT_PROVIDER_AVAILABILITY
, column name : AVAILABILITY_DATE_TIME
and #start_date and #enddate as params
Thanks in advance
It does not ignore the time portion.
Check your data- that you really do have a record in that range
Check your culture settings- that it's not treating the string '2/11/2010' as '11/2/2010' when converting it to a datetime
Change your parameter assignment. Even if your culture setting is right you should still use an unambiguous value for the assignment. Something more like this: 2010-02-11 11:31:00 AM
Check your parameter definitions, that you're not using the newer 'date' type.
If all else fails, write it out in long hand: WHERE ([column] >= #startdate AND [column] <= #enddate)

How can I compare two datetime fields but ignore the year?

I get to dust off my VBScript hat and write some classic ASP to query a SQL Server 2000 database.
Here's the scenario:
I have two datetime fields called fieldA and fieldB.
fieldB will never have a year value that's greater than the year of fieldA
It is possible the that two fields will have the same year.
What I want is all records where fieldA >= fieldB, independent of the year. Just pretend that each field is just a month & day.
How can I get this? My knowledge of T-SQL date/time functions is spotty at best.
You may want to use the built in time functions such as DAY and MONTH. e.g.
SELECT * from table where
MONTH(fieldA) > MONTH(fieldB) OR(
MONTH(fieldA) = MONTH(fieldB) AND DAY(fieldA) >= DAY(fieldB))
Selecting all rows where either the fieldA's month is greater or the months are the same and fieldA's day is greater.
select *
from t
where datepart(month,t.fieldA) >= datepart(month,t.fieldB)
or (datepart(month,t.fieldA) = datepart(month,t.fieldB)
and datepart(day,t.fieldA) >= datepart(day,t.fieldB))
If you care about hours, minutes, seconds, you'll need to extend this to cover the cases, although it may be faster to cast to a suitable string, remove the year and compare.
select *
from t
where substring(convert(varchar,t.fieldA,21),5,20)
>= substring(convert(varchar,t.fieldB,21),5,20)
SELECT *
FROM SOME_TABLE
WHERE MONTH(fieldA) > MONTH(fieldB)
OR ( MONTH(fieldA) = MONTH(fieldB) AND DAY(fieldA) >= DAY(fieldB) )
I would approach this from a Julian date perspective, convert each field into the Julian date (number of days after the first of year), then compare those values.
This may or may not produce desired results with respect to leap years.
If you were worried about hours, minutes, seconds, etc., you could adjust the DateDiff functions to calculate the number of hours (or minutes or seconds) since the beginning of the year.
SELECT *
FROM SOME_Table
WHERE DateDiff(d, '1/01/' + Cast(DatePart(yy, fieldA) AS VarChar(5)), fieldA) >=
DateDiff(d, '1/01/' + Cast(DatePart(yy, fieldB) AS VarChar(5)), fieldB)
Temp table for testing
Create table #t (calDate date)
Declare #curDate date = '2010-01-01'
while #curDate < '2021-01-01'
begin
insert into #t values (#curDate)
Set #curDate = dateadd(dd,1,#curDate)
end
Example of any date greater than or equal to today
Declare #testDate date = getdate()
SELECT *
FROM #t
WHERE datediff(dd,dateadd(yy,1900 - year(#testDate),#testDate),dateadd(yy,1900 - year(calDate),calDate)) >= 0
One more example with any day less than today
Declare #testDate date = getdate()
SELECT *
FROM #t
WHERE datediff(dd,dateadd(yy,1900 - year(#testDate),#testDate),dateadd(yy,1900 - year(calDate),calDate)) < 0