I am using SQL Server 2017. I am trying to handle strings from a free format field and either convert them to a date in the format of "dd/mm/yyyy" or if they are not in this format then simply display the text verbatim.
I need this in a VIEW so can not use SET LANGUAGE. Sounds simple using Convert and IsDate but does not seem to work.
So for the snippet of code below (remember this will be in a view), I want to read the text and if the string converts to a date (ie. is in the format dd/mm/yyyy then run the convert to a date as I need it in date format for Excel to pick up (via Connect SQL Server database)), and if it does not convert to a date then display the text as it is.
create table dateTest1
(
idx int,
dateStringTest varchar(15)
);
insert into dateTest1 (idx, dateStringTest)
values (1, '13/01/2021'), (2, 'no');
select
case
when isdate(convert(datetime, dateStringTest, 103)) = 1
then convert(datetime, dateStringTest, 103)
else dateStringTest
end as dtres
from
dateTest1
--where idx = 1
Error:
Msg 241, Level 16, State 1, Line 15
Conversion failed when converting date and/or time from character string.
This error happens for idx = 2. Idx = 1 works ok.
Any assistance with this would be greatly appreciated. Thanks in advance.
You need to cast your resulting date to a varchar. A case expression can only return a single data type and the order-of-precedence means it is still trying to convert the varchar values to datetime
select
case when isdate( dateStringTest) = 1
then Cast(convert(datetime, dateStringTest, 103) as varchar(10))
else dateStringTest
end as dtres
from dateTest1
You can compact into a single statement (the same order of precedence applies)
select IsNull(Cast(Convert(datetime,Try_Cast(dateStringTest as date),103) as varchar(10)),dateStringTest)
from datetest1
Based on the syntax you are using, I assume you are using SQL Server. You should add the appropriate tag to your question.
The only way to do that in one column is to leave it as text.
Your use of ISDATE() is incorrect. If dateStringTest is not a valid date, CONVERT() on SQL Server will throw an error like:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
That's why you get an error for idx=2
You say you "need it in date format for Excel to pick up". How Excel interprets it will probably depend on your locale settings. Assuming mm/dd/yyyy is valid in your locale, Excel probably already sees it as a date. But I assume that's not happening, so mm/dd/yyyy is not valid for your locale. For me, if I have this table in SQL...
create table dateTest1 (
id int identity(1,1) not null,
dateStringTest varchar(20)
)
insert dateTest1
values
('2020-01-01')
, ('2020-21-01')
, ('2020-01-21')
, ('1/1/2020')
, ('1/21/2020')
, ('21/1/2020')
, ('21/01/2020')
, ('other stuff')
...and query it from Excel, adding columns with the functions DATEVALUE, DAY, WEEKDAY, and YEAR, I get...
id
dateStringTest
DATEVALUE
DAY
WEEKDAY
YEAR
1
2020-01-01
43831
1
4
2020
2
2020-21-01
#VALUE!
#VALUE!
#VALUE!
#VALUE!
3
2020-01-21
43851
21
3
2020
4
1/1/2020
43831
1
4
2020
5
1/21/2020
43851
21
3
2020
6
21/1/2020
#VALUE!
#VALUE!
#VALUE!
#VALUE!
7
21/01/2020
#VALUE!
#VALUE!
#VALUE!
#VALUE!
8
other stuff
#VALUE!
#VALUE!
#VALUE!
#VALUE!
That seems to indicate that Excel is recognizing some of the values as dates.
What you need to do is try to convert the value to datetime, then if it fails report the original value. In both cases, output a string.
You should review the documentation for CONVERT().
Try this:
select dateStringTest
, coalesce(cast(try_convert(datetime, dateStringTest, 103) as varchar(20)), dateStringTest) as dtres1
, coalesce(convert(varchar(20), try_convert(datetime, dateStringTest, 103), 103), dateStringTest) as dtres2
, coalesce(convert(varchar(20), try_convert(datetime, dateStringTest, 103), 101), dateStringTest) as dtres3
from dateTest1
UPDATE
If you are considering only values matching the pattern dd/mm/yyyy as dates (so 17/01/2021 is a date and 17/1/2021 is not), this brute force method will work with SQL Server 2008 (compatibility level 100):
(Notice I updated my input, also, above.)
;
with a as (
select id
, dateStringTest
, SUBSTRING(dateStringTest, 7, 4) + '-' + SUBSTRING(dateStringTest, 4, 2) + '-' + SUBSTRING(dateStringTest, 1, 2) as converteDate
from dateTest1
)
select id
, cast(convert(datetime, dateStringTest, 103) as varchar(20)) as dtres
from a
where isdate(converteDate) = 1
union
select id
, dateStringTest as dtres
from a
where isdate(converteDate) = 0
I've got a table in Teradata that stores a date in an 8 character INT field in the following form "YYYYMMDD", so for today it would store "20180308". If I try to CAST it as a date like this:
CAST(date_field AS DATE FORMAT 'YYYY-MM-DD')
It transforms the date to some future date in the year 3450 or something.
I think it's an error that this data isn't either stored as a date object. Is there anyway to overcome this glitch? I don't have access to change this unfortunately.
Thanks
It's not an 8 character integer, it's an 8 digit integer.
Teradata stores dates using
(year - 1900) * 10000
+ (month * 100)
+ day
This results in 1180308 for today and 20180308 will return 3918-03-08
To cast it to a date you need to use
cast(intdate-19000000 as date)
select cast('20180308' as date format 'yyyymmdd') ;
I have a value stored as Varchar(50) as "2016-07-21 16:35:05". I want to add 5 minutes to it. How do I do it? Expected output "2016-07-21 16:40:05" as a Varchar.
I've so far tried converting the value to DATETIME and adding 5 minutes. But when I try to convert it back to varchar, it doesn't show up in the same format.
SELECT
CAST(DATEADD(MINUTE, 5, CAST([PickTime] AS DATETIME)) AS VARCHAR(50))
FROM
rawdata
Output I get: Jul 21 2016 4:40PM
But I wanted: 2016-07-21 16:40:05
Could anyone guide me ?
Thanks
SELECT FORMAT(DATEADD(MINUTE, 5, cast([PickTime] as datetime)),'yyyy-MM-dd HH:mm:ss')
FROM rawdata
I am working on trying to list every item that hasn't changed in the last month but when I run this query:
select * from AGLT.LTB0040 WHERE wdate> current_date - 6 MONTHS
I get an error message saying that the value is not valid. I have checked the dates listed in the field and they are 20160101. Any idea on where I have gone wrong?
If date column is a representation of a date make a string or numeric comparison.
If the date is a 8 char field
WHERE wdate >= varchar_format(current
timestamp- 6 months,'YYYYMMDD')
If the date is 8,0 field
WHERE wdate >= cast( varchar_format(current
timestamp- 6 months,'YYYYMMDD') as decimal(8,0))
I have column of 24 hr and i need to change it to 12 hr, Please help .
Start time
174300
035800
023100
The result should be
Start time
05.43 PM
03.58 AM
02.31 AM
Use STUFF function to convert string to Time format
SELECT CONVERT(VARCHAR,CAST(STUFF(STUFF(ColumnName,3,0,':'),6,0,':') AS TIME),100)
Using one of the examples above - the following will work.
You need to split the data into hours/minutes and cast it to time format, than convert it to the relevant type:
declare #data int
set #data = 174300
select convert(VARCHAR(15),cast(cast(left(#data, 2 )as varchar(2)) + ':' + cast(substring(cast(#data as nvarchar(6)), 3,2 )as varchar(2) ) as time),100)
Don't store time as varchar, instead alter your table and change the column type to datetime.
SELECT right(convert(varchar(25), Start Time, 100), 7)
The 100 you see in the function specifies the date format mon dd yyyy hh:miAM (or PM), and from there we just grab the right characters.
You can see more about converting datetimes here.