TSQL Null data to '' replace - sql

I have the following query:
SELECT pics.e_firedate FROM et_pics
Result:
NULL
2014-12-01 00:00:00.000
2015-04-03 00:00:00.000
NULL
NULL
I want to replace NULL values to ''.
CASE
WHEN pics.e_firedate IS NULL THEN ''
ELSE pics.e_firedate
END
makes NULL transforming to 1900-01-01 00:00:00.000, which I've tried to cast and replace with no success also.
How can I achive my goal?

That's because when using CASE expressions, the return values must have the same data type. In case they have different data types, all values are converted to the type with a higher data type precedence.
And since DATETIME has a higher datatype than VARCHAR, '' gets converted to DATETIME:
SELECT CAST('' AS DATETIME)
The above will return 1900-01-01 00:00:00.000.
To achieve your desired result, you should CAST the result to VARCHAR
SELECT
CASE
WHEN e_firedate IS NULL THEN ''
ELSE CONVERT(VARCHAR(23), e_firedate, 121)
END
FROM et_pics
For date formats, read this.

Try:
select isNUll(CONVERT(VARCHAR, pics.e_firedate, 120), '') e_firedate
FROM et_pics

SELECT
ISNULL(CONVERT(varchar(10),pics.e_firedate,120),'') e_firedate
FROM et_pics

You have to cast/convert datetime field, not other value - for example:
case
when pics.e_firedate is null
then ''
else cast(pics.e_firedate as nvarchar(30))
end

Well, the column in your database seems to be a DATETIME column. So SQL Server converts '' to the default date value.
One solution might be to convert all the results to string, as in:
SELECT ISNULL(CONVERT(NVARCHAR, pics.e_firedate), '') AS e_firedateString
FROM et_pics

Might be more efficient? And might not.
SELECT CONVERT(VARCHAR(23), e_firedate, 121) FROM et_pics where pics.e_firedate is not null
union
SELECT '' FROM et_pics where pics.e_firedate is null

Related

Cast to datetime only if its a date value

I have a table with DateFrom column
it's an nvarchar col in the col I have data like that
01
02
10/10/2020
04
some strings and some DateTime values
I need to cast it to DateTime but only if it's a date if not then pull out the value like it is can is this possible?
thanks ...
a Simple Try cast should do the job here
DECLARE #Table TABLE (Val NVARCHAR(20))
INSERT INTO #Table
VALUES('1'),('2'),('10/10/2020'),('04')
SELECT
*,
TRY_CAST(Val AS DATE)
FROM #Table
Results
Something like this should work. It uses a CASE statement to check whether or not the value is a valid date and if so casts it to DATETIME, then converts it to VARCHAR (so dates and other values can be returned as the same column).
You can find other datetime to string styles here if you need them formatted differently:
https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver15
DECLARE #TempTable TABLE (Dt NVARCHAR(30))
INSERT INTO #TempTable
VALUES('1'),('2'),('10/10/2020'),('04'),('Jun 27 2021 12:22AM'),('Oct 12 2021 8:31PM')
SELECT
*,
CASE WHEN ISDATE(Dt) = 1 THEN Convert(VARCHAR, CAST(Dt AS DATETIME), 120) ELSE Dt END
FROM #TempTable
You can easily check this with the case statement.
Postgres example
select case when '12/12/2021' ~ '\d{2}\/\d{2}\/\d{4}' then 'this is the date' ELSE 'this is a string' end;
->this is the date
select case when 'some text' ~ '\d{2}\/\d{2}\/\d{4}' then 'this is the date' ELSE 'this is a string' end;
->this is a string
so you can use it like this
select case when fild_01 ~ '\d{2}\/\d{2}\/\d{4}' then TO_DATE(fild_01,'DD/MM/YYYY')::text ELSE fild_01 end from test_table;
as you can see, case construction can't generalize two different types of data, so I had to convert them to the same type of text
Use the TRY_CONVERT function, with style 107
SELECT TRY_CONVERT(datetime, 'Jun 27 2021 12:22AM', 107)
Result
2021-06-27 00:22:00.000
This returns a null if the value is not a date
You can choose according to your needs.
When you want to set default value:
SELECT IIF(ISDATE(Val) = 1 , Val,'YOUR_DEFAULT_VALUE')
Whent default value not matter (It will be NULL):
SELECT TRY_CAST(NULL AS DATE)

Filter Data in SQL Server

I have a table like below :
[TMP_TBL]
(
...
[DT_REFUND] [varchar(20)] NULL,
[MSG_PROCESS] [nvarchar(max)] NULL,
...
)
and it contains data like this:
| DT_REFUND | MSG_PROCESS |
| A-BC---D | WRONG DATETYPE |
| 20180301 | NULL |
| 20180331 | NULL |
When I do a query like:
select *
from TMP_TBL
where isnull(MSG_PROCESS, '') = ''
everything goes fine.
But when I do query like:
select *
from TMP_TBL
where isnull(MSG_PROCESS, '') = ''
and convert(DATE, DT_REFUND) >= convert(DATE, '20180301');
I get an error:
Conversion failed when converting date and/or time from character string
Why did this happen, and how to fix it?
Thanks
Ideally you should have avoided using VARCHAR data type for dates.
For the current scenario, you can use TRY_CONVERT like following.
select *
from TMP_TBL
where isnull(MSG_PROCESS, '') = ''
and TRY_CONVERT(DATE, DT_REFUND) >= convert(DATE, '20180301');
As your date column is VARCHAR, so there is a possibility of having empty spaces also, to handle this you can try RTRIM function before converting to date like following.
TRY_CONVERT(DATE, RTRIM(DT_REFUND)) >= convert(DATE, '20180301');
First you check the value in the column is DATE format or other format, using ISDATE function. And compare with the date value.
If it is not in date format it returns NULL value.
Try this:
SELECT *
FROM TMP_TBL
WHERE ISNULL(MSG_PROCESS,'') = ''
AND CONVERT(DATE, CASE WHEN ISDATE(DT_REFUND)=1 THEN DT_REFUND ELSE NULL END) >= CONVERT(DATE, '20180301');
You just need to filter out null values and compared date via cast() or convert() function
select *
from TMP_TBL
where MSG_PROCESS is null and
cast(DT_REFUND as date) >= '20180301';
This assumes null value has always date as your sample data suggests
In other way, first you could check DT_REFUND has some kind of date format data via TRY_CONVERT() function. So, your where clause should do
where MSG_PROCESS is null and TRY_CONVERT(date, DT_REFUND) is not null and
cast(DT_REFUND as date) >= '20180301';
However, the above has some redundant filtration before cast so you could also express that as
where MSG_PROCESS is null and TRY_CONVERT(date, DT_REFUND) >= '20180301';

How to skip values that have NULL values in a TSQL query?

I have this rather complex query:
SELECT distinct
v.KodQ, v.DodPeriodika,
v.GodGP, v.Periodika as Period,
k.Oblast, k.KratokNazivSI,
k.NazivSI, k.Periodika,
v.rKod, r.Naziv,
v.rDatum,
v.IT, v.Primerok, v.BrojIE,
CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodOd), 103) as RefPeriodOd,
CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodDo), 103) as RefPeriodDo
FROM GP.dbo.MyTable1 AS v
INNER JOIN GP.dbo.MyTable2 as k
ON k.KodSI = v.KodQ AND k.DodObr = v.DodPeriodika
INNER JOIN GP.dbo.MyTable3 AS r
ON r.rKod = v.rKod
WHERE v.GodGP = GodGP and CHARINDEX('-', RefPeriodDo, 0) != 0
I need to convert v.RefPeriodOd and v.RefPeriodDo from this format '31-Dec-2017' to this format '31/12/2017'.
Yes I know saving DateTime as string(varchar) is bad idea, but the application is now in use so I cannot really do QA at the moment and refactor my table.
I am using this statement:
CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodDo), 103) as RefPeriodDo
But the problem is, v.RefPeriodOd and v.RefPeriodDo can have a NULL values and also values in the format: '31/12/2017'
If I remove this condition:
CHARINDEX('-', RefPeriodDo, 0) != 0
I get this error:
The conversion of a nvarchar data type to a datetime data type
resulted in an out-of-range value.
How can I add some conditions in the query?
Does IF statement exists in TSQL?
Change
CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodOd), 103) as RefPeriodOd
for
CASE
WHEN CHARINDEX('-', RefPeriodDo, 0) != 0
THEN CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodOd), 103)
END as RefPeriodOd
And remove the filter in the WHERE.
"IFs" are expressed with the CASE clause if inside SELECT statements, and the most common syntax is the following:
CASE
WHEN 1stCondition THEN 1stValue
WHEN 2ndCondition THEN 2ndValue
ELSE DefaultValue -- Else is optional
END
Conditions are evaluated in order, and if no ELSE is issued, then NULL is returned.
Try to add to the where the following:
WHERE (v.RefPeriodOd is not null and v.RefPeriodOd <> '')
AND (v.RefPeriodDo is not null and v.RefPeriodDo <> '')
Note:
You cannot put the condition in the WHERE clause. The filtering is not necessarily before the expressions in the SELECT.
You should always include a length for strings in SQL Server.
The right way to handle this is try_convert():
TRY_CONVERT(varchar(255), TRY_CONVERT(DATETIME, v.RefPeriodOd), 103) as RefPeriodOd,
TRY_CONVERT(varchar(255), TRY_CONVERT(DATETIME, v.RefPeriodDo), 103) as RefPeriodDo
TRY_CONVERT() is available since SQL Server 2012. Before that, you needed to use a CASE to avoid conversion errors.
In my opinion, the filter condition should be:
RefPeriodDo LIKE '%-%'
I think this is easier to write and to read.
Try this:
SELECT distinct
v.KodQ, v.DodPeriodika,
v.GodGP, v.Periodika as Period,
k.Oblast, k.KratokNazivSI,
k.NazivSI, k.Periodika,
v.rKod, r.Naziv,
v.rDatum,
v.IT, v.Primerok, v.BrojIE,
CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodOd), 103) as RefPeriodOd,
CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodDo), 103) as RefPeriodDo
FROM GP.dbo.MyTable1 AS v
INNER JOIN GP.dbo.MyTable2 as k
ON k.KodSI = v.KodQ AND k.DodObr = v.DodPeriodika
INNER JOIN GP.dbo.MyTable3 AS r
ON r.rKod = v.rKod
WHERE v.GodGP = GodGP AND ISNULL(v.RefPeriodOd,'')<>'' AND ISNULL(v.RefPeriodDo,'')<>''
Filter the rows using WHERE:
WHERE v.GodGP = GodGP AND ISNULL(v.RefPeriodOd,'')<>'' AND ISNULL(v.RefPeriodDo,'')<>''
Give this as try
Note the double use of 103
declare #D table (id int identity primary key, dt varchar(20));
insert into #D (dt) values (null), ('messy'), ('31-Dec-2017'), ('31/12/2017'), ('1/12/2017');
select d.dt
, TRY_CONVERT(DATETIME, d.dt, 103) as dt103
, isnull(TRY_CONVERT(varchar(20), TRY_CONVERT(DATETIME, d.dt, 103), 103), d.dt) dt103var
from #D d;
dt dt103 dt103var
-------------------- ----------------------- --------------------
NULL NULL NULL
messy NULL messy
31-Dec-2017 2017-12-31 00:00:00.000 31/12/2017
31/12/2017 2017-12-31 00:00:00.000 31/12/2017
1/12/2017 2017-12-01 00:00:00.000 01/12/2017

select query to return datetime from string value

I have the following sql query
Select ISNULL([SaleDate] ,'Totals') AS [DispTotals],
case when SaleDate is null then ' ' else CONVERT(datetime, SaleDate, 103) end AS [DayOfDateDD],
FROM ()------
The result of a sql query
DispTotals DayOfDateDD
26/05/2013 2013-05-26 00:00:00.000
27/05/2013 2013-05-27 00:00:00.000
Totals 1900-01-01 00:00:00.000
I know the last row of SaleDate is null value.
when i change the query like:
Select ISNULL([SaleDate] ,'Totals') AS [DispTotals],
case when SaleDate is null then 'NULLVALUE ' else 'NONULL' end AS [DayOfDateDD],
The result is:
DispTotals DayOfDateDD
26/05/2013 NONULL
27/05/2013 NONULL
Totals NULLVALUE
I want an empty space when there is a null value(NULLVALUE) in SaleDate.
I am not sure how to figure this out.
Any help please.
CONVERT(datetime, NULLIF(SaleDate, ''), 103)
has helped to avoid 1900-01-01 00:00:00.000
You want to display a blank instead of NULL for a date field? Since blank casts as 1900... default date value, you'd have to convert back to VARCHAR:
CAST(ISNULL(CASE WHEN SaleDate IS NULL
THEN NULL
ELSE CONVERT(datetime, SaleDate, 103)
END,''),AS VARCHAR(20))
If the inside CONVERT statement returns a NULL then you can get rid of the CASE statement altogether, and just keep the CAST(ISNULL( wrapper.

Is there a safe way to cast SQL datetimes?

Pretty simple question that I can't quite find the answer for:
Is there a simple and safe† way to cast a varchar to datetime in SQL Server?
† i.e. gracefully handle non-datetime strings with a default datetime value
You can filter your rows using the isdate function. This query returns three rows without any conversion errors:
with v as (
select '20110714' value union all
select '2011-07-15' union all
select '3/22/2011' union all
select 'foo'
)
select cast(value as datetime)
from v
where isdate(value) = 1
Edit
When you want a default vaue (like the current date/time), you could do something like this:
select case when isdate(value) = 1 then cast(value as datetime) else getdate() end
From SQL Server Denali you can use TRY_CONVERT. A case expression is the only safe way in previous versions.
You could try
select cast ('28/08/2006 11:23:25' as datetime)
SELECT * FROM tab_val WHERE (CASE ISDATE(val) WHEN 1 THEN CAST(val As DateTime) ELSE NULL END)
More details in the manual
we can place a check that column have the valid datetime and if not then return nulls not genrating any error.
SELECT CASE ISDATE([YourDate]) WHEN 0
THEN CAST([YourDate] AS DATETIME)
ELSE CAST(NULL AS DATETIME) END AS [Your Date]
FROM [dbo].[yourtable]