If/then/else in SQL Query - sql

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.

Related

Handling a value of zero in a date datatype

I'm reporting out of a database that is using decimal(17,6) as the datatype for a date field. For example, the current date/time in this field would be 20210820.171900. Unusual, but whatever. I need to convert the original date field from decimal(17,6) to datetime. This is what I have:
SELECT convert(datetime, convert(varchar,convert(int, lastmoddatetime)), 0)
from Table1
The above statement works correctly as long as none of the records have a value of zero in this column. Unfortunately, the column value defaults to zero (0.000000) if no date has been calculated for it. Whenever a column has a zero value, I get the following error:
Conversion failed when converting date from character string.
How can I overcome this issue? Ultimately, I'm needing to apply a dateadd function to the lastmoddatetime field.
Note: Before you suggest changing the column definition, this database originated in the 1990's and I'm not allowed to make any changes to the database structure.
You can use NULLIF to null out those values
convert(datetime, convert(varchar(15), convert(int, NULLIF(lastmoddatetime, 0.0))), 0)
Either use TRY_CONVERT or CASE - depending how you want to handle the zero case.
SELECT
-- If desiring null for 0 and SQL Server 2012+
TRY_CONVERT(date, CONVERT(varchar, CONVERT(int, lastmoddatetime)), 0)
, CASE WHEN lastmoddatetime <> 0
-- If desiring some other valid date or < SQL Server 2012
THEN CONVERT(date, CONVERT(varchar, CONVERT(int, lastmoddatetime)), 0)
ELSE NULL /* Whatever valid datetime value you want */ END
FROM (
VALUES (20210820.171900), (0.0)
) x (lastmoddatetime);
I note that this ignores the time component - so am converting to a date not datetime above. If you need to handle the time component you need to update your question.
Yet another option.
You can thin it out a bit by using left() and try_convert()
Example
Declare #YourTable table (lastmoddatetime numeric(17,6))
Insert into #YourTable values
(20210820.171900)
,(0.0)
Select AsDate = try_convert(date,left(lastmoddatetime,8))
,AsDateTime = try_convert(datetime,left(lastmoddatetime,8))
From #YourTable
Results
AsDate AsDateTime
2021-08-20 2021-08-20 00:00:00.000
NULL NULL
use
convert(datetime,convert(int,lastmoddatetime),0)

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

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)

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: Convert String of MMMDD to Datetime

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

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)