How to solve the date comparison issue in SQL Server? - sql-server

I am using the following way to compare two dates:
if CONVERT(varchar(20), #ScheduleDate, 101) >= CONVERT(varchar(20), #CurrentDateTime, 101)
This is working fine for the current year, but when the comes in yearly like one date is 12/31/2012 and 1/1/2013 then its not working.
Please help me how can I resolve this.

why do you comparing strings?
you can compare dates
if #ScheduleDate >= #CurrentDateTime
but if your date contains time, I usually do
if convert(nvarchar(8), #ScheduleDate, 112) >= convert(nvarchar(8), #CurrentDateTime, 112)
112 datetime format is YYYYMMDD so it's good for compare dates

You have to remember that string comparison is from left to right, so "1/...." is smaller than "12/...".
You need to use DATETIME comparisons, not string comparison.
Something like
DECLARE #ScheduleDate DATETIME = '1/1/2013',
#CurrentDateTime DATETIME = '12/31/2012'
IF (#ScheduleDate >= #CurrentDateTime)
BEGIN
SELECT #ScheduleDate, #CurrentDateTime
END
DECLARE #ScheduleDateString VARCHAR(20) = '1/1/2013',
#CurrentDateTimeString VARCHAR(20) = '12/31/2012'
IF (CONVERT(DATETIME,#ScheduleDateString,101)>=CONVERT(DATETIME,#CurrentDateTimeString,101))
BEGIN
SELECT CONVERT(DATETIME,#ScheduleDateString,101),CONVERT(DATETIME,#CurrentDateTimeString,101)
END
SQL Fiddle DEMO
Note that if the variables are already datetimes, you do not need to convert them.

Assuming that both variables are currently DateTime variables, can't you just compare them without converting to strings?
declare #ScheduleDate DATETIME, #CurrentDateTime DATETIME
SET #ScheduleDate = '1 Jan 2013'
SET #CurrentDateTime = GetDate()
IF (#ScheduleDate >= #CurrentDateTime)
BEGIN
SELECT 'Do Something'
END
ELSE
BEGIN
SELECT 'Do Something Else'
END

when you use CONVERT(nvarchar(8), #ScheduleDate, 112) function it's return string instead of date.
so,
Use "112" DateFormat in Sql Server it's return string in "YMD" format without any sepration.
compare that string in your query and get desire output.
Such as "if CONVERT(nvarchar(8), #ScheduleDate, 112) >= CONVERT(nvarchar(8), #CurrentDateTime, 112)"

I would not use CONVERT to compare formatted strings. It is slow (well, more like microseconds, but still)
I use a UDF for SQL prior to version 2008
CREATE FUNCTION [dbo].[DateOnly] (#Date DateTime)
RETURNS Datetime AS
BEGIN
Return cast (floor (cast (#Date as float)) as DateTime)
END
and for versions >=2008 this approach
select convert(#MyDateTime as DATE)
Of course, you can compare datetime values directly, but to know whether two datetime values are on the same date (ignoring the time component), the above versions have proven to be effectivy.

Date : From and To with following format
from_Date# = #dateformat("#form.from#", "mm/dd/yyyy")
to_Date# = #dateformat("#now()#" + 1, "mm/dd/yyyy")
In SQL Statement
WHERE a.DateCreated >= CAST ('#from_date#' AS DATE) and a.DateCreated <= CAST('#to_date#' AS DATE)
This is working fine without any cast of original date time column

Related

SQL convert date dmmyyyy and ddmmyy to yyyy-mm-dd

I have the following problem.
I have some dates with the following format '15122019' and I need it in this format 2019-12-15, which I already solved it in the following way.
select convert (date, Stuff(Stuff('15122018',5,0,'.'),3,0,'.'),104)
The real problem is when the dates come like this '3122019' the conversion can not be done because the length is shorter. Is ther e another way to do it? I've been trying to solve it for several hours. And another question, can this query be parameterized?
Try this:
DECLARE #date VARCHAR(20)
SET #date ='3122019'
IF(LEN(#date) = 8)
BEGIN
SET #date = Stuff(Stuff(#date,5,0,'.'),3,0,'.');
SELECT CONVERT(DATE, #date , 103);
END
ELSE IF(LEN(#date) = 7)
BEGIN
SET #date = Stuff(Stuff(#date,4,0,'.'),2,0,'.');
IF(ISDATE(#date)=1)
BEGIN
SELECT CONVERT(DATE, #date , 103);
END
ELSE
BEGIN
SET #date = Stuff(Stuff(#date,4,0,'.'),3,0,'.');
SELECT CONVERT(DATE, #date , 103);
END
END
ELSE IF(LEN(#date) = 6)
BEGIN
SET #date = Stuff(Stuff(#date,3,0,'.'),2,0,'.');
SELECT CONVERT(DATE, #date , 103);
END
You can add 0 to the left and take 8 chars with right. like RIGHT('0'+'15122018',8). it work with 15122018 and 3122018
select convert (date, Stuff(Stuff( RIGHT('0'+'15122018',8) ,5,0,'.'),3,0,'.'),104)
Such conversation can be achieved by:
Casting integer value to DATE using intermediate FORMAT transformation to a recognizable for conversation string pattern.
style 105 applied to match the input as dd-mm-yyyy
style 05 to match dd-mm-yy
SQL:
-- input format: dmmyyyy
SELECT CONVERT(DATE, FORMAT(3012019, '##-##-####'), 105)
-- result: 2019-01-03
-- input format: dmmyy
SELECT CONVERT(DATE, FORMAT(30119, '##-##-##'), 05)
-- result: 2019-01-03
This will work fine with a single (and double) digit day number, however, it indeed requires a double-digit month

Convert VARCHAR in format YYMMDD to YYYYMMDD and ignore invalid date formats

I have a table with a VARCHAR field called ArrivalDate in format yymmdd (such as 170202).
I am writing a query which converts it to yyyymmdd so it should become 20170202.
However my problem is that I need to cater for the case when inappropriate data is entered into the field, and my query needs to exclude that data. I am achieving this exclusion by using the ISDATE function of TSQL. I also need to select the least recent entry (I'm using order by asc for this).
I am using a variety of converts to write this query, below is my implementation with a sample table and data.
Declare #tmp TABLE (theDates VARCHAR(MAX))
INSERT INTO #tmp VALUES('170202')
SELECT TOP 1 t.theDates
WHEN (ISDATE(t.theDates) = 1) THEN CONVERT( VARCHAR(max),CONVERT(datetime t.theDates), 112)
FROM #tmp t
WHERE (ISDATE(t.theDates) = 1)
ORDER BY CAST(t.theDates as DATE)
However I do not like my approach and it occasionally fails conversion and throws an error with values such as 02/02/02 which breaks the query. Can someone please show me a better way of writing this functionality.
Much appreciated!
You can use TRY_CONVERT and CONVERT to get the correct format and convert the value. Then check that the string is exactly 6 character to prevent other formats from being returned.
SELECT
convert(char(10),convert(date, theDates, 12),112)
FROM
(values('02/02/02'),('170202')) x(theDates)
WHERE
try_convert(date, theDates, 12) is not null
and len(theDates) = 6
You can use cast(#date as datetime)
declare #date varchar(max);
set #date='170202';
select
CASE WHEN (ISDATE(cast(#date as datetime)) = 1)
THEN CONVERT(VARCHAR(max), CONVERT(datetime, cast(#date as datetime)), 112) end
from table
set #date='02/02/02';
select
CASE WHEN (ISDATE(cast(#date as datetime)) = 1)
THEN CONVERT(VARCHAR(max), CONVERT(datetime, cast(#date as datetime)), 112) end
from table
please use create function for check dateformat is Valid or not and use this fun in your query inside cash clouse.
ALTER FUNCTION dbo.f_CheckDate
(#InDate nvarchar(25))
RETURNS DATE
AS
BEGIN
declare #Return DATETIME
select #return = CASE WHEN ISDATE(#InDate) = 1
THEN #InDate
ELSE NULL
END
return #return
END
You could use TRY_CAST or TRY_CONVERT if value cannot be cast it will return NULL.
SELECT
TRY_CAST('20170228' AS DATETIME),
TRY_CAST('170228' AS DATETIME),
TRY_CONVERT(DATETIME, '20170228'),
TRY_CONVERT(DATETIME, '170228')
This works for SQL Server 2012 and newer.

Replace only the date part

This question may be duplicate sorry for it,As I could not able to find any solution in web till now so am Posting this
I need to create a SQL server functions where I need to replace only the date part from the actual date ..
For example if the actual date is 01/10/2016 means I need to update the actual date to 15/10/2016 the date part alone is replaced from 01 to 15 I need to achieve this, please help me in solving this as am very new to SQL SERVER
DECLARE #actual_due_date INT = 5;
DECLARE #invoice_date DATETIME = '20161210';
DECLARE #due_date DATETIME;
SET #due_date=DATEADD(DAY,#actual_due_date-DATEPART(DAY,#invoice_date),#invoice_date);
SELECT #due_date;
This prints out
2016-12-05 00:00:00.000
Here's another way to do it:
DECLARE #oldDate DATETIME = '2016-10-17 10:29:22'
DECLARE #replacingDate DATE = '2016-10-15'
DECLARE #newDate DATETIME
SET #newDate = CONVERT(datetime, CONVERT(varchar, #replacingDate)+' '+ LEFT(CONVERT(varchar, CONVERT(time, #oldDate)), 8))
SELECT #newDate
--UPDATE TableA
--SET FieldX = CONVERT(datetime, CONVERT(varchar, #replacingDate)+' '+ LEFT(CONVERT(varchar, CONVERT(time, #oldDate)), 8))
--WHERE SomeCondition
Don't know, what you really try to achieve, but you could try this:
DECLARE #OtherDate DATETIME = {ts'2016-02-05 12:00:00'}; --Some day in February, 12 o'clock
DECLARE #actualDate DATETIME = GETDATE(); --current day and time
--This comes back with the other date, but the actual time
SELECT CAST(CAST(#OtherDate AS date) AS datetime) + CAST(CAST(#actualDate AS time) AS datetime);
Not sure of the purpose, why you are replacing it.
Here is one way:
Declare #date date = '01/10/2016'
Select Replace(Convert(varchar(20), #date, 101), '01/', '15/') AS ReplacedDate
-- 15/10/2016

How to get date from yyyy-mm-dd to yyyy-mm-dd in SQL?

I want to get date from yyyy-mm-dd to yyyy-mm-dd in SQL.
Example: I have two parameter #startdate : 2015-12-28 and #enddate : 2016-01-02, and database in SQLServer, datatype is varchar(10)
DATE_ORDER
28-12-2015
30-12-1996
29-12-2016
30-12-1997
24-12-2015
27-12-1993
03-01-2016
01-01-1992
02-01-2016
etc...
Ok,now I want to get data from #startdate : 2015-12-28 and #enddate : 2016-01-02. I use SELECT * FROM TABLE_X WHERE DATE_ORDER >= #startdate AND DATE_ORDER <= #enddate . But the results are not what I expected. Here are the results I want
28-12-2015
30-12-1996
29-12-2016
30-12-1997
01-01-1992
02-01-2016
I think to solve this problem, I need to do two things :
First, get date range from #startdate to #enddate , in here 28/12/2015, 29/12/2015, 30/12/2015, 31/12/2015, 01/01/2016, 02/01/2016.
The second: get the date in database same in range 28/12, 29/12, 30/12, 31/12, 01/01, 02/01, ignoring the year.
Can you give me some ideas about this ?
Your actual format is "105-italian" find details here.
You can convert your existing VARCHAR(10)-values with this line to real datetime
SELECT CONVERT(DATETIME,YourColumn,105)
Next thing to know is, that you should not use BETWEEN but rather >=StartDate AND < NakedDateOfTheFollowingDay to check date ranges
So to solve your need Get date-range from 2015-12-28 to 2016-01-02 you might do something like this:
DECLARE #Start DATETIME={d'2015-12-28'};
DECLARE #End DATETIME={d'2016-01-02'};
SELECT *
FROM YourTable
WHERE CONVERT(DATETIME,YourDateColumn,105)>=#Start AND CONVERT(DATETIME,YourDateColumn,105)<#End+1
Attention Be aware, that the conversion lets your expression be not sargable. No index will be used.
Better was to store your date as correctly typed data to avoid conversions...
Try this query
SET DATEFIRST 1
DECLARE #wk int SET #wk = 2
DECLARE #yr int SET #yr = 2011
--define start and end limits
DECLARE #todate datetime, #fromdate datetime
SELECT #fromdate = dateadd (week, #wk, dateadd (YEAR, #yr-1900, 0)) - 4 -
datepart(dw, dateadd (week, #wk, dateadd (YEAR, #yr-1900, 0)) - 4) + 1
SELECT #todate = #fromdate + 6
;WITH DateSequence( Date ) AS
(
SELECT #fromdate AS Date
UNION ALL
SELECT dateadd(DAY, 1, Date)
FROM DateSequence
WHERE Date < #todate
)
--select result
SELECT * FROM DateSequence OPTION (MaxRecursion 1000)
So, after the 2nd or 3rd edit, it slowly becomes clear, what you want (i hope).
So you REALLY WANT to get the dates with the year beeing ignored.
As someone pointed out already, date-values are stored internally not as string, but as internal datatype date (whatever that is in memory, i don't know).
If you want to compare DATES, you cannot do that with ignorance of any part. If you want to, you have to build a NEW date value of day and month of given row and a hard coded year (2000 or 1 or whatever) for EVERY row.
SELECT * FROM TABLE_X WHERE convert(date,'2000' + substring(convert(char(8),convert(datetime, 'DATE_ORDER', 105),112),5,4),112) >= #startdate AND convert(date,'2000' + substring(convert(char(8),convert(datetime, 'DATE_ORDER', 105),112),5,4),112) <= #enddate
If your startdate and enddate go OVER sylvester, you have to do 2 queries, on from startdate to 1231, one from 0101 to enddate.

Conversion failed when converting date and/or time from character string in SQL SERVER 2008

I have below SQL.
UPDATE student_queues
SET Deleted=0,
last_accessed_by='raja',
last_accessed_on=CONVERT(VARCHAR(24),'23-07-2014 09:37:00',113)
WHERE std_id IN ('2144-384-11564')
AND reject_details='REJECT'
when I ran the above SQL the below exception has been throwed.
Conversion failed when converting date and/or time from character string.
If you're trying to insert in to last_accessed_on, which is a DateTime2, then your issue is with the fact that you are converting it to a varchar in a format that SQL doesn't understand.
If you modify your code to this, it should work, note the format of your date has been changed to: YYYY-MM-DD hh:mm:ss:
UPDATE student_queues
SET Deleted=0,
last_accessed_by='raja',
last_accessed_on=CONVERT(datetime2,'2014-07-23 09:37:00')
WHERE std_id IN ('2144-384-11564') AND reject_details='REJECT'
Or if you want to use CAST, replace with:
CAST('2014-07-23 09:37:00.000' AS datetime2)
This is using the SQL ISO Date Format.
Seems like last_accessed_on, is a date time, and you are converting '23-07-2014 09:37:00' to a varchar. This would not work, and give you conversion errors. Try
last_accessed_on= convert(datetime,'23-07-2014 09:37:00', 103)
I think you can avoid the cast though, and update with '23-07-2014 09:37:00'. It should work given that the format is correct.
Your query is not going to work because in last_accessed_on (which is DateTime2 type), you are trying to pass a Varchar value.
You query would be
UPDATE student_queues SET Deleted=0 , last_accessed_by='raja', last_accessed_on=convert(datetime,'23-07-2014 09:37:00', 103)
WHERE std_id IN ('2144-384-11564') AND reject_details='REJECT'
DECLARE #FromDate DATETIME
SET #FromDate = 'Jan 10 2016 12:00AM'
DECLARE #ToDate DATETIME
SET #ToDate = 'Jan 10 2017 12:00AM'
DECLARE #Dynamic_Qry nvarchar(Max) =''
SET #Dynamic_Qry='SELECT
(CONVERT(DATETIME,(SELECT
CASE WHEN ( ''IssueDate'' =''IssueDate'') THEN
EMP_DOCUMENT.ISSUE_DATE
WHEN (''IssueDate'' =''ExpiryDate'' ) THEN
EMP_DOCUMENT.EXPIRY_DATE ELSE EMP_DOCUMENT.APPROVED_ON END
CHEKDATE ), 101)
)FROM CR.EMP_DOCUMENT as EMP_DOCUMENT WHERE 1=1
AND (
CONVERT(DATETIME,(SELECT
CASE WHEN ( ''IssueDate'' =''IssueDate'') THEN
EMP_DOCUMENT.ISSUE_DATE
WHEN (''IssueDate'' =''ExpiryDate'' ) THEN EMP_DOCUMENT.EXPIRY_DATE
ELSE EMP_DOCUMENT.APPROVED_ON END
CHEKDATE ), 101)
) BETWEEN '''+ CONVERT(CHAR(10), #FromDate, 126) +''' AND '''+CONVERT(CHAR(10), #ToDate , 126
)
+'''
'
print #Dynamic_Qry
EXEC(#Dynamic_Qry)

Resources