SQL: Convert String of MMMDD to Datetime - sql

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

Related

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)

Regular expression for mm/yy in Microsoft SQL Server

I am trying to execute a regular expression in SQL Server to match a MM/YY formatted VARCHAR string.
I have tried
WHERE ExpiryDate LIKE '[0-9][0-9]/[0-9][0-9]'
which allows incorrect dates like 30/18.
I also tried
WHERE ExpiryDate LIKE '0[1-9]|1[012]/[0-3][0-9]'
But SQL Server does not accept pipe separated as an OR operator.
I need the month to match 01 - 12
I can do
WHERE ExpiryDate LIKE '0[1-9]/[0-9][0-9]'
OR ExpiryDate LIKE '10/[0-9][0-9]'
OR ExpiryDate LIKE '11/[0-9][0-9]'
OR ExpiryDate LIKE '12/[0-9][0-9]'
but I would prefer it to be within the regular expression.
Thanks in advance for any help.
If 2012+, you could use try_convert() to convert the expiration string into a date. Try_Convert() will return a NULL value if the conversion fails.
Example
Declare #YourTable table (ID int, ExpiryDate varchar(25))
Insert Into #YourTable values
(1,'09/17')
,(2,'30/17')
Select *
From #YourTable
Where try_convert(date,replace(ExpiryDate,'/','/01/')) >= '2017-09-01'
-- Where try_convert(date,replace(ExpiryDate,'/','/01/')) is null
Returns
ID ExpiryDate
1 09/17
If you need to convalidate dates, you could try something like this:
SET DATEFORMAT dmy
;WITH A AS (SELECT '18/12' AS EXPDATE UNION ALL SELECT '10/17' UNION ALL SELECT 'x2/16' )
SELECT *, ISDATE('01/'+EXPDATE) AS CHK FROM A
Output:
EXPDATE CHK
18/12 0
10/17 1
x2/16 0
date LIKE '0[1-9]/[0-9][0-9]' OR
date LIKE '1[0-2]/[0-9][0-9]'
Is much shorter. But without | it is hard to make variants... Notice, that LIKE takes not regexes, but wildcards.
Don't forget, that '[1-9]/[0-9][0-9]' can also happen. And other variants, with inner spaces and so on. If you are not absolutely sure in month format used, and don't depend on high speed, use #JohnCampeletti variant.

SQL server 2012 error converting date from string when selecting date with like

In my table, I have a datetime NULL field called logDate.
The format stored: 2014-03-28 12:24:00.000
I have a form and the log date is one of the fields for searching logs.
The user will enter the date like 2014-03-28
So in my SELECT procedure I need to use a LIKE:
#logDate datetime =NULL
.
.
SELECT .. FROM mytable WHERE
(#logDate IS NULL OR CONVERT(VARCHAR, #logDate, 102) LIKE '%'+logDate+'%')
I execute the procedure:
EXEC dbo.SELECT_mytable #logDate= '2014-03-28'
But I get the following error:
Conversion failed when converting date and/or time from character string.
What am I doing wrong?
You also need to convert the logdate column to a varchar, I think you have your LIKE the wrong way around as you are trying to find the user entered date within the date column, so try:
SELECT .. FROM mytable WHERE
(#logDate IS NULL
OR '%'+CONVERT(VARCHAR, #logDate, 102)+'%' LIKE CONVERT(VARCHAR, logDate, 102))
As others have indicated (and I should have pointed out) you shouldn't be converting Dates to Strings in-order to search date columns, much better to keep everything in a DateTime format for performance.
This will work, provided that you change your stored procedure to expect the #logDate parameter as a DateTime:
SELECT .. FROM mytable WHERE
(#logDate IS NULL
OR logDate = #logDate)
I get the impression that you went down the string comparison route because you wanted to ignore the time element and just search on date, if that is the case you can strip the time from both elements and just match on date by doing this:
IF #logDate IS NOT NULL
BEGIN
// Remove any time element
SET #logDate = DATEADD(dd,0, DATEDIFF(dd,0,#logDate))
END
SELECT .. FROM mytable WHERE
(#logDate IS NULL
OR DATEADD(dd,0, DATEDIFF(dd,0,logDate)) = #logDate)

Convert String to date in select statement

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

If/then/else in SQL Query

I would like to check a date value in my SQL query. If a date is equal to a predefined date then do not print anything, ELSE print the existing date value.
How can I write it correctly in order to take the desired date value ?
I have the following query:
(SELECT (CASE
WHEN (PaymentsMade.PaymentDate = '09/09/1987') THEN ' '
ELSE PaymentsMade.PaymentDate
END)
) as dateOfPayment
When I run this query it works correctly when the date is equal to '09/09/1987' , whereas when the date is not equal to '09/09/1987' it prints '01/01/1900'.
How can I retrieve the dates values that are not equal to the predefined date '09/09/1987'?
Any advice would be appreciated.
Thanks
The CASE clause needs to return a consistently-typed value, so it is implicitly converting a space to a date (which is evaluated as 1 Jan 1900).
You have two choices:
select a null instead of a blank space.
explicitly cast the date in the else condition to a string.
Here's an (implicit) example of the former:
SELECT (CASE WHEN PaymentsMade.PaymentDate <> '09/09/1987'
THEN PaymentsMade.PaymentDate
END)
as dateOfPayment
Use NULL, not empty string
An empty string is cast to zero implicitly, which is '01/01/1900'
SELECT CAST('' AS datetime)
Using a CASE statement changes the value in that field, but doesn't change which rows are returned.
You appear to want to filter out rows, and if that is the case, use a WHERE clause...
SELECT
*
FROM
PaymentsMade
WHERE
PaymentDate <> '09/09/1987'
You could use NULLIF to replace a specific date with a NULL:
SELECT NULLIF(PaymentsMade.PaymentDate, '09/09/1987')
FROM ...
Don't just use an empty string, because it would be converted to the type of PaymentDate, which is probably a datetime, and an equivalent datetime for '' would be 1900-01-01 00:00:00.000.