Trying to eliminate '1900-01-01' from converted date column - sql

I realise that there are other threads covering this but I can't find one that solves my problem.
I have three text columns that either contain a date or nothing (null), I'm converting the text to a date in order to use date filters once the date makes it to Excel.
Obviously, the null values get converted to '1900-01-01' but I can't find a way to show them as blanks, even with a subquery.
This is what I'm doing...
Select top 999999999
OtherFields,
case when Engdate = '19000101' then '' else Engdate end as 'EngDate',
OtherOtherFields
from
(
select
OtherFields,
case
when VAR_AppID = '3' then nullif( CONVERT(date,concat(right([2201],4),
SUBSTRING([2201],4,2), left([2201],2))),null)
else nullif( CONVERT(date,concat(right([3429],4),
SUBSTRING([3429],4,2), left([3429],2))),null) end as 'Engdate',
case when ([2201] is not null and Len([2201]) = 10 ) then
CONVERT(date,concat(right([2201],4), SUBSTRING([2201],4,2), left([2201],2)))
else null end as 'EngagementRec',
OtherOtherFields
from
Tables
)
The fields [2201], and [3429] are the text fields that contain the dates in 'dd/mm/yyyy' format.
Am I supposed to covert back to a text format to allow the '' to show a blank - and if so, will the dates still be recognised as dates?

As per answer of Anthony Green on sqlservercentral, you may try:
ISNULL(CONVERT(varchar, DateTimeColumnName,23),'') as DateTimeColumnName

Yes, Converting them text first won't do any bad (I think).
Try the following:
Select top 999999999
OtherFields,
case when Engdate = '19000101' then '' else CONVERT(CHAR(10), EngDate, 120) end as 'EngDate' end as 'EngDate',
OtherOtherFields
from
(
select
OtherFields,
case
when VAR_AppID = '3' then nullif( CONVERT(date,concat(right([2201],4),
SUBSTRING([2201],4,2), left([2201],2))),null)
else nullif( CONVERT(date,concat(right([3429],4),
SUBSTRING([3429],4,2), left([3429],2))),null) end as 'Engdate',
case when ([2201] is not null and Len([2201]) = 10 ) then
CONVERT(date,concat(right([2201],4), SUBSTRING([2201],4,2), left([2201],2)))
else null end as 'EngagementRec',
OtherOtherFields
from
Tables
)
Thanks.

As you may know, converting an empty string to the date datatype returns 1900-01-01.
Example SQL:
SELECT CAST ('' as date) AS [thedate]
Returns:
thedate
1900-01-01
The NULL value, when casted to the date datatype is still NULL.
Based on your code, I think all you have to do is change this line:
case when Engdate = '19000101' then '' else Engdate end as 'EngDate',
to:
case when Engdate = '19000101' then NULL else Engdate end as 'EngDate',

I'm closing this one myself as I can't find anything that works.
Any combination of case statments, ISNULL(), NULLIF() etc result in either NULL or '1900-01-01'. Converting to text makes the date field unusable in Excel.
As the data will be coming into an Excel pivot table, I don't desperately need to resolve this as pivot tables eliminate null values anyway.
...I might come back to this if I need to show the data in a list.
Thanks to everyone that made suggestions!

According to the ms help on the Concat function (which is sql 2012 onwards not 2008)
https://learn.microsoft.com/en-us/sql/t-sql/functions/concat-transact-sql?view=sql-server-2017
If CONCAT receives arguments with all NULL values, it will return an empty
string of type varchar(1).
A zero length string will be implicitly converted to zero giving you the zero date in sql server. You need to handle the nulls before trying to convert the way you have done it.
Maybe use Try_convert instead.
Use try_convert with the right option.
TRY_CONVERT(Datetime, columnwithstringdate, 103)

Related

SQL Null dates return 1900-01-01

Here is part of my query:
IsNull(CONVERT(date, V_CONSTAT_ACTUAL_DATES.ID50), '') AS 'actualFinish'
V_CONSTAT_ACTUAL_DATES.ID50 is a NULL and is a datetime column. So the results I get is 1900-01-01, what I am trying to do is return nothing just ' ' How would I accomplish this?
The mixing of types you have now is definitely a problem.
If you want to display an empty string for a null date you need convert the date into a short date time string not a date. You can use the convert function to do that. The last parameter accepts a style code so you can have it display just the date part.
COALESCE(CONVERT(varchar(8), V_CONSTAT_ACTUAL_DATES.ID50, 101), '') AS 'actualFinish'
This will display the date in mm/dd/yy format if the column is not null, or an empty string if it is.
To see more about date to string conversions go to https://msdn.microsoft.com/en-us/library/ms187928.aspx.
Rather than ISNULL or COALESCE try using a CASE statement -
SELECT CASE WHEN date IS NULL THEN '' ELSE CONVERT(date, V_CONSTAT_ACTUAL_DATES.ID50) END
Simple ISNULL Nested CAST function can remove 1900-1-1 value if data is NULL
ISNULL(CAST(CAST(<<DateColumn>> AS DATE) AS Varchar),' ') [<<Date Column Name>>]

SQL-Should I use nested Query to first correct erroneous data and then convert to datetime?

There is one column: OpenedDate with datatype: varchar(8) and I want to convert it into datetime but since OpenedDate has erroneous values of 0's.
First- I want to convert the 0's into NULLs using the query:
CASE WHEN Opened_dt = '0'
then 'NULL'
else Opened_dt
end as 'Opened_dt_converted'
Now, I want to use the above results to convert the datatype to DateTime using the syntax:
CONVERT(DATETIME, 'Opened_dt_converted',120)
I was thinking if I should use Nested query or create a stored procedure but I am not sure how can I use the nested query for this type of situation?
Basically, I want this whole query in one stored procedure. Could you please help me in achieving that task?
Thanks in advance!
Geetanjali
If you are using SQL Server 2012+, just use try_convert():
select try_convert(DateTime, OpenedDate, 120)
If it fails, then you'll get NULL. In older versions, you would just use a case:
select (case when OpenedDate like '[0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]'
then convert(DateTime, OpenedDate, 120)
end)
Note: I just put in a format that would often work for date. The time component is similar.
Sub-select or CTE should work for you.
SELECT CONVERT(DATETIME, Opened_dt_converted, 120) AS dt_converted
FROM (SELECT CASE
WHEN Opened_dt = '0' THEN NULL
ELSE Opened_dt
END AS Opened_dt_converted
FROM yourtable) a
or use Case statement to skip the zero from convertion
SELECT CASE
WHEN Opened_dt = '0' THEN NULL
ELSE CONVERT(DATETIME, Opened_dt, 120)
END AS dt_converted
FROM yourtable

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.

How do I get valid dates, like using the ISDATE function without removing Null values?

Good day everyone!
I am using the T-SQL ISDATE() function with a date column as argument to filter out bad dates; the problem is the ISDATE function will return zero when it comes across a NULL value.
So with the example below; valid data in the table will be left out of the result set if there is a null for their dates. How can I remedy this so that I can get valid dates but also retrieve records with no dates? I need the records with no dates as well, I only need to remove those with bad dates, example, incomplete dates or dates missing characters.
Example:
SELECT * FROM EXAMPLE WHERE ISDATE(MAYDATE) <> 0
Thanks my friends!
You could either use the ISNULL function, to replace the NULL value with a valid date value that is just used by the ISDATE function. Here are two examples:
SELECT * FROM EXAMPLE WHERE ISDATE(ISNULL(MAYDATE, '1/1/1900')) <> 0
SELECT * FROM EXAMPLE WHERE ISDATE(ISNULL(MAYDATE, GETDATE())) <> 0
Or just check to see if the the value is NULL
SELECT * FROM EXAMPLE WHERE (ISDATE(MAYDATE) <> 0) OR (MAYDATE IS NULL)
try:
SELECT * FROM EXAMPLE WHERE ISDATE(MAYDATE) <> 0 OR MAYDATE IS NULL
Check for nulls first
SELECT * FROM EXAMPLE WHERE MAYDATE is null or ISDATE(MAYDATE) <> 0
SELECT * FROM EXAMPLE WHERE (MAYDATE IS NOT NULL AND ISDATE(MAYDATE) <> 0)
OR (MYDATE IS NULL)

SQL Server: Using a case statement to see if a date is NULL and if it is returning ' '

I have a column in my select statement that looks like this:
SELECT CASE WHEN fu.SentOutDate IS NULL THEN '' ELSE fu.SentOutDate END
This returns 1900-01-01 00:00:00.000 for the ones that would otherwise be NULL
I know this because when I put in just fu.SentOutDate it comes up as NULL
Why does this happen and how can I just get it to return a blank value?
Try converting the date to a string so it doesn't try to convert '' to a date:
(CASE WHEN fu.SentOutDate IS NULL THEN '' ELSE CONVERT(varchar,fu.SentOutDate) END)
It's casting your '' to a DATETIME, since your other column you'd return is a datetime column.
SELECT CASE WHEN 1=1 THEN '' ELSE GETDATE() END
will give you the same value...
You can convert this to a varchar(32), but I'm not certain of the ramifications
SELECT CASE WHEN 1=1 THEN '' ELSE CAST(GETDATE() AS varchar(32)) END
A column can only return one data type - DATETIME != string/VARCHAR.
If you want a zero length string in the event of the value being NULL, you have to explicitly change the data type, using CAST/CONVERT to change the non-NULL value to a VARCHAR/etc data type.
If you're just checking for NULL values, you might try ISNULL() and cast the date as a varchar.
SELECT ISNULL(CAST(fu.SentOutDate AS VARCHAR(50)), '') AS SendOutDate
FROM tablename
It sounds like you're displaying this value in a GUI or client somewhere. In my opinion, the best practice is to convert it from the NULL value there, not in the query.
If you ever create a database that scales to millions of users, you want a little processing as possible in the database and as much as possible in the client. Doing conversion of a date to character is an unneeded load on the system (character calculation is always much slower than math).
This may work:
case when ISNULL(convert(varchar, a.rec_dt, 108), '00:00:00')='00:00:00' then ''
else CAST(rec_dt as varchar)