SQL Server clean up inconsistent dates - sql

I have dates currently stored as varchar(1000) that are in inconsistent formats. I.e. yyyy-mm-dd and dd-mm-yyyy etc.
What query can I run to clean these up so they are in a consistent format, so I can convert the column datatype from varchar(1000) to date?
Thanks

This could get ugly if you have many different date formats, possibly including invalid data. One option would be to assign a new date column using a CASE expression to choose the correct format mask:
UPDATE yourTable
SET date_col = CASE WHEN date LIKE '[0-9]{2}-[0-9]{2}-[0-9]{4}'
THEN CONVERT(datetime, date, 105)
WHEN date LIKE '[0-9]{4}-[0-9]{2}-[0-9]{2}'
THEN CONVERT(datetime, date) END;
You may add conditions to the above CASE expression for other date formats.

Related

SQL, casting a string to date so I can use GETDATE()

I am using SQL Server Management Studio 18 against SQL Server 2016. I have some material that are in batches and those batches have expiration dates that are held as strings, but are basically in the format of 'yearmonthday', e.g. '20210312' for March 3rd, 2021. My goal is to only see material that is expiring after the current date. Whenever I try to CAST the expiration date column AS DATE within the WHERE clause, I get this error:
Conversion failed when converting date and/or time from character string
(or something similar when trying different methods).
So, right now my code looks like this:
SELECT MaterialColumn, BatchColumn, CAST(ExpirationColumn AS DATE)
FROM StockTable
WHERE CAST(ExpirationColumn AS DATE) > CAST(GETDATE() AS DATE)
If I don't do the WHERE clause, I know I can CAST the ExpirationColumn as DATE without issue, but when it's in the WHERE clause, I run into that error. Is there any way I can filter to see only the dates that I want?
You can use try_cast() instead:
SELECT MaterialColumn, BatchColumn, CAST(ExpirationColumn AS DATE)
FROM StockTable
WHERE TRY_CAST(ExpirationColumn AS DATE) > CAST(GETDATE() AS DATE);
You can also find the bad values:
SELECT ExpirationColumn
FROM StockTable
WHERE TRY_CAST(ExpirationColumn AS DATE) IS NULL AND ExpirationColumn IS NOT NULL;
It sounds like you might need to fix some data values.
Honestly, if your dates are all stored in the format yyyyMMdd then there's no need to convert. Instead use a varchar parameter, as (at least) a varchar in the format yyyyMMdd had the same sort order as a date.
As a result you just convert GETDATE to the right format:
WHERE Expiration > CONVERT(varchar(8), GETDATE(), 112)
Of course, this doesn't change my statements in the comment; fix your design, don't stores dates as a string but as a date (and time) data type.

Parse values of different type to date

I'm trying to parse certain columns into a date format and have had success doing so, but have run into an error due to inconsistency that lies in the data.
My date columns are currently integers in the form of YYYYMMDD, so I've used the following in the select statement to parse into dates:
CONVERT(datetime, CAST(date_column AS CHAR(8)), 112)
This works as expected, transforming my data into a YYYY-MM-DD format.
I run into the following error though:
Conversion failed when converting date and/or time from character
string.
After looking through the data a bit, it turns out I have some cases of inconsistent data values, such as -1 and 10630 instead of the expected YYYYMMDD value.
Do I just need to add a WHERE statement to only apply CONVERT and CAST to YYYYMMDD fields while filtering out fields with bad data? If so, how would I do this, or is there a better way?
Thanks in advance
Let me assume you are using SQL Server, based on the syntax of your SQL. You shouldn't actually need the 112. 'YYYYMMDD' is the default date format for SQL Server.
In any case, you can use TRY_CONVERT():
TRY_CONVERT(datetime, CAST(date_column AS CHAR(8)), 112)
This returns NULL if the value cannot be converted. You can find the offending values using:
select date_column
from t
where try_convert(datetime, cast(date_column as char(8)) is null and
date_column is not null;
Use Parse() or Try_parse()
select parse('22-JAN-1989' as date)
select parse('04-March-1992' as date)
select parse('03/10/2020' as date)
select parse('07-05-1958' as date)
select parse('Aug 25,2016' as date)
Every example above returns a valid date.
You can also add USING 'en-US' or such if you want a different culture.
If you are getting numeric values, and you know the starting date, use
select IsNull(try_parse('16500' as date),dateadd(d,cast('16500' as int),'1/1/1980'))

How to convert column type from str to date when the str is of format dd/mm/yyyy?

I have a large table in sql I imported from a large csv file.
A column is recognized as a str when it contains date information of format dd/mm/yyyy.
I tried select TO_DATE('12/31/2015') as date but that does not work because TO_DATE function needs yyyy-mm-dd format.
How can I rearrange the '12/31/2015' string to '2015-12-31' format inside sql so that I can convert the column type to date?
I am doing this on a sparkSQL (on databricks environment ) due to the very large size of the data where the update keyword of sql does not seem to be supported.
Just re-read your question;
I would suggest this:
UPDATE table
SET column = Convert(varchar(10), Convert(smalldatetime, column, 103), 120)
This converts the column value to smalldatetime, using the british format (dd/mm/yyyy), then converts it back to varchar, using the 120 format (yyyy-mm-dd); The 120 format contains time info, but this will be truncated because it's being cast back as varchar(10);
Test it:
SELECT Convert(varchar(10), Convert(smalldatetime, column, 103), 120)
FROM table
The below link answer works
https://forums.databricks.com/answers/12121/view.html
df.withColumn("tx_date", to_date(unix_timestamp($"date", "M/dd/yyyy").cast("timestamp")))

Convert Data from yyyy-dd-mm to mm/dd/yyyy Issue

I have a column in my table with Dates in the format yyyy-mm-dd I want to convert all the dates in that column to the format mm/dd/yyyy
I am using the below query
UPDATE Test.dbo.Status
SET DateIn = CONVERT(DATE,DateIn ,101)
The DateIn column is defined as Date in my table (DateIn DATE NULL)
The query does no change to the data. am I doing some thing wrong here?
You can change the default format in which SQL Server displays a date, but you can't alter the way a DATE value is stored via CONVERT(). You can format a date however you want if you store it as a string, but you lose functionality when you do that and it's not advisable. If you are hell-bent on storing a formatted version, you might want to create a new VARCHAR() field so you can preserve your DATE version.
You're better off formatting the date at the application level.
The reason your query does nothing is that the actual DATE values are equivalent. Notice when you take any valid date format and CAST() it as DATE the resulting format is the same regardless of the input:
SELECT CAST('20040510' AS DATE)
SELECT CAST('2004-05-10' AS DATE)
SELECT CAST('May 10, 2004' AS DATE)
All return: 2004-05-10 on my instance of SQL Server.

I want to convert a whole column into the date format of yyyymmdd, I do not want the current date

I want to convert a whole column into the date format of yyyymmdd, I do not want the current date, thus I cannot use getdate() command, there is already data in the column, I just need the right command to convert the whole column into yyyymmdd format.
The column I am using is FIELD_034 and the table is Sur_CompassAuto1_1_7_fetch.
I am using SQL Server.
Thank you
I fully agree with the paqogomez's response, but instead of date style of 111, better use 112.
The output for the statement
SELECT CONVERT(VARCHAR(10), FIELD_034, 111)
will result in yyyy/MM/dd. Where as,
SELECT CONVERT(VARCHAR(10), FIELD_034, 112)
will return yyyyMMdd, which is what he needed.
A common misconception is that a datetime has a format. If you are storing your dates as a datetime, then you can output it in any format.
It sounds as though you might be storing your values as a Varchar. You would be better off converting your varchar dates into a datetime, then you can do whatever you want with them
That said, if you HAVE FIELD_034 as a DateTime, then its as easy as
SELECT CONVERT(VARCHAR(10), FIELD_034, 112)
from Sur_CompassAuto1_1_7_fetch
If the field is a varchar its similar:
SELECT CONVERT(datetime, FIELD_034, 112)
from Sur_CompassAuto1_1_7_fetch
The difficulty of this one is if you have your values in different or nonstandard formats. Then it would require some clean up to make the query work.
Edit: as #AArnold says, its 112 instead of 111. Date formats are subtle.