Convert String to date in select statement - sql

I have a column which contains data but the problem is that this column has data type of varchar(50) and it has to be this due to some reasons,now what i want to do is while selecting data from table , i want to treat this column as date so that i can use it in where clause. i am using the code below for converting it yo date , but it converts some values and then gives an error
this is my sample data
8/1/2002
6/9/2001
14/9/2001
26/7/2001
14/12/2001
21/1/2002
29/4/2001
7/5/2001
9/11/2001
16/7/2001
select CONVERT(date,sowingDate,103) from tblAgriculture_staging
I have tried which differnt version of date format e.g 103,105 etc
but still it converts some values but error comes on some values and query execution stops

Try this:
SET DATEFORMAT dmy;
select case when isdate(sowingDate) = 1 then CONVERT(date,sowingDate,103) end [date] from tblAgriculture_staging
or (if you are using sql 2012)
SET DATEFORMAT dmy;
select case when TRY_CONVERT(date, sowingDate) IS NOT NULL then CONVERT(date,sowingDate,103) end [date] from tblAgriculture_staging
but this solution hides (convert to NULL) all dates that are wrong. You can reverse the condition first and find/fix all rows with incorrect date (i.e. 31/02/2013) and then use this queries to show only valid dates
SQLFiddle

but it converts some values and then gives an error this is my sample
data
because some data are in invalid format or contains incorrect symbols.
Try this:
select CONVERT(date,ltrim(rtrim(sowingDate)), 103) from tblAgriculture_staging
or examine your values:
select ISDATE(sowingDate) as IsDate, sowingDate, CASE WHEN ISDATE(sowingDate)=1 THEN CONVERT(date,ltrim(rtrim(sowingDate)), 103) ELSE NULL END from tblAgriculture_staging

This is slightly crappy, but so is storing dates as varchar.
this is code that has worked for me in the past where i had some dates with 4 digit years and some with 2 digit years.
where (TRY_CONVERT(Datetime2,LTRIM(RTRIM([INVC DTE])),1)>=#From
AND TRY_CONVERT(Datetime2,LTRIM(RTRIM([INVC DTE])),1)<=#To)
OR (TRY_CONVERT(Datetime2,LTRIM(RTRIM([INVC DTE])),101)>=#From
AND TRY_CONVERT(Datetime2,LTRIM(RTRIM([INVC DTE])),101)<=#To)
SQL Server 2012 + Only
This assumes you have cleaned up anything that actually just isn't a date...

This will return all the dates that are not actually dates.
select sowingDate from tblAgriculture_staging where isdate(sowingDate)=0

Related

Why isn't SQL Server letting me store '21/04/17' as a date?

I've got a table that currently has all columns stored as nvarchar(max), so I'm converting all the datatypes to be what they should be. I have a column of dates, however when I run this:
ALTER TABLE Leavers ALTER COLUMN [Actual_Termination_Date] date;
I get
"Conversion failed when converting date and/or time from character string".
This is relatively normal, so I did the following to investigate:
SELECT DISTINCT TOP 20 [Actual_Termination_Date]
FROM LEAVERS
WHERE ISDATE([Actual_Termination_Date]) = 0
which returned:
NULL
13/04/2017
14/04/2017
17/04/2017
19/04/2017
21/04/2017
23/04/2017
24/04/2017
26/04/2017
28/04/2017
29/03/2017
29/04/2017
30/04/2017
31/03/2017
42795
42797
42813
42817
42820
42825
The null and excel style date formats (e.g. 42795) are no problem, however it's the ones appearing as perfectly normal dates I'm having a problem with. I usually fix issues like this by using one of the following fixes:
SELECT cast([Actual_Termination_Date] - 2 as datetime)
FROM LEAVERS
WHERE ISDATE([Actual_Termination_Date]) = 0
or
SELECT cast(convert(nvarchar,[Actual_Termination_Date], 103) - 2 as datetime)
FROM LEAVERS
WHERE ISDATE([Actual_Termination_Date]) = 0
When these return back the dates as I would expext, I'd then do an UPDATE statement to change them in the table and then convert the column type. However I keep getting an error message telling me that various dates can't be converted such as:
Conversion failed when converting the nvarchar value '21/04/2017' to data type int.
Any thoughts? Thanks!
Probably because of your language setting. For '21/04/2017' to work, you'll need to be using the BRITISH language, or other language that uses dd/MM/yyyy. I suspect you are using ENGLISH which is actually American.
American's use MM/dd/yyyy meaning that '21/04/2017' would mean the 4th day of the 21st month in the year 2017; obviously that doesn't work.
The best method is to use an unambiguous format, regardless of language and data type. For SQL Server that's yyyyMMdd and yyyy-MM-ddThh:mm:ss.nnnnnnn (yyyy-MM-dd and yyyy-MM-dd hh:mm:ss.nnnnnnn are not unambiguous in SQL Server when using the older datetime and smalldatetime data types).
Otherwise you can use CONVERT with a style code:
SELECT CONVERT(date,'21/04/2017', 103)
The problem with your data, however, is that you have values that are in the format dd/MM/yyyy and integer values. The int (not varchar) value 42817 as a datetime in SQL Server is 2017-03-25. On the other hand, if this data came from Excel then the value is 2017-03-23. I am going to assume the data came from Excel, not SQL Server (because the ACE drivers have a habit of reading dates as numbers, because the thing they aren't is "ace").
You'll need to therefore convert the values to an unambiguous format first, so that'll be yyyyMMdd. As we have 2 different types of values, this is a little harder, but still possible:
UPDATE dbo.Leavers
SET Actual_Termination_Date = CONVERT(varchar(8), ISNULL(TRY_CONVERT(date, Actual_Termination_Date, 103), DATEADD(DAY, TRY_CONVERT(int, Actual_Termination_Date),'18991230')), 112);
Then you can alter your table:
ALTER TABLE dbo.Leavers ALTER COLUMN [Actual_Termination_Date] date;
DB<>Fiddle using MichaƂ Turczyn's DML statement.
Put the column into a canonical format first, then convert:
update leavers
set Actual_Termination_Date = try_convert(date, [Actual_Termination_Date], 103);
ALTER TABLE Leavers ALTER COLUMN [Actual_Termination_Date] date;
The update will do an implicit conversion from the date to a string. The alter should be able to "undo" that implicit conversion.
Back up the table before you do this! You are likely to discover that some dates are not valid -- that is pretty much the rule when you store dates as strings although in a small minority of cases, all date strings are actually consistently formatted.
The actual date does not matter. The error happens when you try to subtract 2 from a string:
[Actual_Termination_Date] - 2
The clue comes from the error message:
Conversion failed when converting the nvarchar value '21/04/2017' to data type int.
To fix the problem, use DATEADD after the conversion:
SELECT DATEADD(days, -2, convert(datetime, [Actual_Termination_Date], 103))
You just have inconsistent date format within your column, which is terrible.
Having wrong datatype lead to it, that's why it is so important to have proper data types on columns.
Let's investigate it a little:
-- some test data
declare #tbl table (dt varchar(20));
insert into #tbl values
(NULL),
('13/04/2017'),
('14/04/2017'),
('17/04/2017'),
('19/04/2017'),
('21/04/2017'),
('23/04/2017'),
('24/04/2017'),
('26/04/2017'),
('28/04/2017'),
('29/03/2017'),
('29/04/2017'),
('30/04/2017'),
('31/03/2017'),
('42795'),
('42797'),
('42813'),
('42817'),
('42820'),
('42825');
-- here we handle one format
select convert(date, dt, 103) from #tbl
where len(dt) > 5
or dt is null
-- here we handle excel like format
select dateadd(day, cast(dt as int), '1900-01-01') from #tbl
where len(dt) = 5
So, as you can see you have to apply to different approaches for this task. CASE WHEN statement should fit here nicely, see below SELECT:
select case when len(dt) = 5 then
dateadd(day, cast(dt as int), '1900-01-01')
else convert(date, dt, 103) end
from #tbl

SQL Server - Value passes ISDATE() but fails to CAST as DATE or DATETIME

I have a varchar column in my database table, on the row I would like to return it is populated as '2018-12-26T00:00:00.000' (quotes mine, not included in actual value). When I try to query for this value whenever it is a valid date, e.g.
SELECT
myValue
FROM
myTable
WHERE
ISDATE(myValue) = 1
it returns properly. However, I need this value to be converted to DATE. When I try something like this:
SELECT
CAST(myValue AS DATE) AS myValueFormatted
FROM
myTable
WHERE
ISDATE(myValue) = 1
I get an error
Conversion failed when converting date and/or time from character string
Is there any other way I can convert this varchar value to Date?
UPDATE: I've noticed through trying some different things, the query seems to be fine with me using the value as a date for anything (DATEDIFF, CONVERT back to string, etc.) in the select portion, but trying to do anything with it in the WHERE clause causes the error. To ensure nothing else is interfering, I created a temp table with only 1 row with the data value above, and running the query just against that one value gives the error
UPDATE 2: Ok, I have no idea why this fixes it, but this is what I found. When I run
SELECT
myValue
FROM
myTable
WHERE
TRY_CONVERT(DATE, myValue) IS NOT NULL
it returns EXACTLY the same values as
SELECT
myValue
FROM
myTable
WHERE
ISDATE(myValue) = 1
However, when I then add AND CAST(myValue AS DATE) < GETDATE() to each WHERE clause, only the first one works. I understand why TRY_CONVERT is safer to use, I'm still not sure why it works over GETDATE()
I can't reproduce your error...
declare #dt varchar(256) = '2018-12-26T00:00:00.000'
select cast(#dt as date)
So, there must be another rogue value in there that can't be converted.
To identify what value is causing the issue on versions < 2012, run this:
SELECT
myValue
FROM myTable
WHERE
ISDATE(myValue) = 0
Note, ISDATE is deterministic only if you use it with the CONVERT function, if the CONVERT style parameter is specified, and style is not equal to 0, 100, 9, or 109.
For 2012 onward, use TRY_CONVERT
SELECT
*
FROM myTable
WHERE
TRY_CONVERT(date, myValue) IS NULL
You could also just try something like this:
SELECT CAST(LEFT(MyValue, 10) AS DATE)
If it still doesn't work, you have some formatting issues with your data.
This helped me....
CAST string as varchar(30) then cast the varchar as datetime2
CAST(CAST(REPLACE(['Timestamp' ],'''','') AS varchar(30)) as datetime2)

Convert VARCHAR to DATE in SQL SERVER

I have VARCHAR column (MyValue) in my table. It has date value in two different format.
MyValue
----------
25-10-2016
2016-10-13
I would like to show them in DATE format.
I wrote query like below:
SELECT CONVERT(date, MyValue, 105) FROM MyTable
SELECT CAST(MyValue as date) FROM MyTable
Both are giving me this error. Conversion failed when converting date and/or time from character string.
Is there anyway convert to DATE datatype format even the value stored in different formats like above?
Expecting your answers. Thanks in advance.
Does this help?
declare #varchardates table
(
vcdate varchar(20)
)
INSERT INTO #varchardates VALUES
('25-10-2016'),
('2016-10-13')
SELECT CONVERT(date,vcdate, case when SUBSTRING(vcdate, 3, 1) = '-'
THEN 105 ELSE 126 END) as mydate
FROM #varchardates
Depending on how many different formats you have in your data, you may need to extend the case statement!
See here for list of the different format numbers
You can use TRY_CONVERT and COALESCE. TRY_CONVERT returns NULL if the conversion fails, COALESCE returns the first NOT NULL value:
SELECT COALESCE(TRY_CONVERT(DATETIME, x, 105), TRY_CONVERT(DATETIME, x, 120))
FROM (VALUES('25-10-2016'), ('2016-10-13')) a(x)
I assumed the value 2016-10-13 is in format yyyy-MM-dd.
You mention in a comment you may have other formats as well. In that case it gets very tricky. If you get a value 01-12-2017 and you have no idea about the format, there is no way to tell whether this is a date in januari or in december.

Convert from nvarchar to datetime from a large record table with potentially bad date strings

I have a main table called Cases that I am inserting data into. I have a alternative table where all of the raw data called rawTableData is stored and then sent to the main table.
I have a nvarchar column in my rawTableDatathat stores a datetime string in this format
2016-04-04-10.50.02.351232
I have a column in my Cases table that has a datatype of DATETIME.
I first tried to find the bad data in this method below
SELECT CONVERT(datetime, nvarcharDateColumn, 103)
FROM rawTableData
WHERE ISDATE(CONVERT(datetime, nvarcharDateColumn, 103)) != 1
And I get the error below
The conversion of nvarchar data type to a datetime data type resulted in an out-of-range value.
Then I tried a different approach hoping to find all of the out of range values
SELECT nvarcharDateColumn
FROM rawTableData
WHERE ISDATE(nvarcharDateColumn)
But that only returns all rows since its nvarchar.
Again, I kept going and tried a different approach
SELECT CONVERT(DATETIME, CASE WHEN ISDATE(nvarcharDateColumn) = 1 THEN nvarcharDateColumn END, 103)
FROM rawTableData
I am not sure what I am doing wrong here and any help would be appreciated.
I am using SQL Server 2012
You can use TRY_CONVERT:
SELECT nvarchardatecolumn, TRY_CONVERT(date, nvarchardatecolumn)
FROM rawTableData
And if you only want to return the invalid dates, use a derived table:
SELECT *
FROM (SELECT nvarchardatecolumn, TRY_CONVERT(date, nvarchardatecolumn) DateCheck
FROM rawTableData
) A
WHERE DateCheck IS NULL

SQL: Convert String of MMMDD to Datetime

I have a nvarchar(5) column of data that is formatted MMMDD (for example, OCT26). With my select statement, I'd like to convert it to a datetime data type with the current year, and then save that datetime value as an alias, say, UsefulDate. So something like 10-26-2012.
Something like: SELECT (whatever SQL gets the job done) AS UsefulDate
The exact formatting doesn't matter; I just need to be able to compare two dates together with greater than and less than operators. Also, sometimes the column will be blank. In that case, I'd like to set the alias to blank as well. Is this possible?
Thanks for your help!
You can convert varchar fields in format MMMDD to date with current year with :
select convert(datetime,'OCT26'+','+cast(year(getdate()) as varchar),107)
So your query would be something like :
select convert(datetime,case varcharDate when '' then null else varcharDate end +
','+cast(year(getdate()) as varchar),107) as UsefulDate
from table
select CASE WHEN ISDATE(mmmdd+' '+right(year(getdate()),4)) = 1
THEN CAST(mmmdd+' '+right(year(getdate()),4) as datetime)
END UsefulDate, *
from tbl