sql date conversion

I have a table that we get from a vendor that has 2 columns

Here is a sample of the data

SDNUID      BirthDate
2674      10 Dec 1948
2683      1938
2687      May 1937
2607      Null

The Birthdate field is defined as varchar(50)

The field contains 'date' in one of 3 formats  (date could have a null value)

dd mmm yyyy


mmm yyyy

What I would like to do is write a query that will return a valid date format by doing the following

if date value is in dd mmm yyyy format then return dd-mmm-yyyy

if date value is in yyyy format then return 01-01-yyyy

if date value is in mmm yyyy format then return 01-mmm-yyyy

if date value is null then return 01-Jan-1900

so using above data example

SDNUID      BirthDate
2674      10-Dec-1948
2683      01-Jan-1938
2687      01-May-1937
2607      01-Jan-1900

I thought of using case statement based on whether length of birthdate field is 11, 4, 8 or 0 but that didn't seem quite right
Who is Participating?
Kyle AbrahamsConnect With a Mentor Senior .Net DeveloperCommented:
Note I'm missing an apostrophe - corrected below:
select SDNUID, replace(convert(varchar, cast(isnull(BirthDate, '1/1/1900') as datetime), 106), ' ', '-')
from yourTable
Russell FoxDatabase DeveloperCommented:
The built-in CAST function will return the dates you want without mucking around with string parsing. You just need to work with the NULL value. That will leave you with a valid DATE field that you can format however you wish (see CONVERT(NVARCHAR...)):

Open in new window

Kyle AbrahamsSenior .Net DeveloperCommented:
select SDNUID, replace(convert(varchar, cast(isnull(BirthDate, '1/1/1900) as datetime), 106), ' ', '-')
from yourTable
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

First, are you wanting to correct the data itself (update statements) or just query the data (select statements)?

If you are correcting the data, you can run a series of updates to address each of the anomolies.

For example:

Update TableName
Set BirthDate= 01-Jan-1900
Where BirthDate=NULL
Scott PletcherConnect With a Mentor Senior DBACommented:
        CASE WHEN BirthDate = 'Null' THEN NULL ELSE '' END +
        CASE WHEN BirthDate LIKE '[0-3][0-9] %' THEN LEFT(BirthDate, 2) ELSE '01' END + '-' +
        CASE WHEN BirthDate LIKE '%[A-Z][A-Z][A-Z]%' THEN SUBSTRING(BirthDate, PATINDEX('%[A-Z][A-Z][A-Z]%', BirthDate), 3) ELSE 'Jan' END + '-' +
        SUBSTRING(BirthDate, PATINDEX('%[12][0-9][0-9][0-9]%', BirthDate), 4)
        , '01-Jan-1900') AS New_Date
    SELECT 2674 AS SDNUID,      '10 Dec 1948' AS BirthDate UNION ALL
    SELECT 2683,      '1938' UNION ALL
    SELECT 2687,      'May 1937' UNION ALL
    SELECT 2607,      'Null'
) AS test_data

Btw, given that you have to modify the data anyway, why not go to the universal format 'YYYYMMDD', which is unambiguous (regardless of dateformat settings), not language dependent, can be directly sorted without any conversion, and saves disk space?
johnnyg123Author Commented:
Thanks for all the posts!!!!

You wouldn't believe it (or maybe you would :-)) ....the requirement has changed slightly

Now I need to only capture valid dates and ignore any others

How would I query to return only those dates that are valid?

Using the sample data above, the query results would just be

2674      10 Dec 1948      

Scott PletcherSenior DBACommented:
That's the other advantage of YYYYMMDD -- can be easily verified :-) .

Use ISDATE() on the value: if you get a 1 result, you can safely convert to a date/datetime.
johnnyg123Author Commented:
Thanks Scott..you pointed me in right direction

I was trying the isdate() of 1 in the query and was getting all rows because sql server thought that all 'dates' were valid

what I really wanted was only dates that were in ddmmmyyyy format so I used following in where clause

replace((BirthDate),' ', '-') = replace(convert(varchar, cast(isnull(BirthDate, '1/1/1900') as datetime), 106), ' ', '-')
johnnyg123Author Commented:
Thanks!  Worked out great!
Scott PletcherSenior DBACommented:
If ISDATE(<string>) returns 1, then CAST(<string> AS date|datetime) should always work correctly.  The only problem would be if you tried to do the conversion yourself, instead of letting SQL do it for you.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.