SQL - Difference between COALESCE and ISNULL? [duplicate] - sql

This question already has answers here:
Using ISNULL vs using COALESCE for checking a specific condition?
(9 answers)
Closed 9 years ago.
What are the practical differences between COALESCE() and ISNULL(,'')?
When avoiding NULL values in SQL concatenations, which one is the best to be used?
Thanks!

Comparing COALESCE and ISNULL
The ISNULL function and the COALESCE expression have a similar purpose but can behave differently.
Because ISNULL is a function, it is evaluated only once. As described above,
the input values for the COALESCE expression can be evaluated multiple
times.
Data type determination of the resulting expression is
different. ISNULL uses the data type of the first parameter, COALESCE
follows the CASE expression rules and returns the data type of value
with the highest precedence.
The NULLability of the result expression is different for ISNULL and COALESCE. The
ISNULL return value is always considered NOT NULLable (assuming the return value is a
non-nullable one) whereas COALESCE with non-null parameters is
considered to be NULL. So the expressions ISNULL(NULL, 1) and
COALESCE(NULL, 1) although equivalent have different nullability
values. This makes a difference if you are using these expressions in
computed columns, creating key constraints or making the return value
of a scalar UDF deterministic so that it can be indexed as shown in
the following example.
> USE tempdb;
> GO
> -- This statement fails because the PRIMARY KEY cannot accept NULL values
> -- and the nullability of the COALESCE expression for col2
> -- evaluates to NULL.
> CREATE TABLE #Demo ( col1 integer NULL, col2 AS COALESCE(col1, 0) PRIMARY KEY, col3 AS ISNULL(col1, 0) );
>
> -- This statement succeeds because the nullability of the
> -- ISNULL function evaluates AS NOT NULL.
>
> CREATE TABLE #Demo ( col1 integer NULL, col2 AS COALESCE(col1, 0),
> col3 AS ISNULL(col1, 0) PRIMARY KEY );
Validations for ISNULL and
COALESCE are also different. For example, a NULL value for ISNULL is
converted to int whereas for COALESCE, you must provide a data type.
ISNULL takes only 2 parameters whereas COALESCE takes a variable
number of parameters.
Source: BOL

The main difference is, that COALESCE is ANSI-Standard, so you will also find it in other RDBMSs, the other difference is you can give a whole list of values to be checked to COALESCE whereas to ISNULL you can only pass one.

Because ISNULL is a function, it is evaluated only once. As described above, the input values for the COALESCE expression can be evaluated multiple times.
COALESCE basically translates to CASE expression and ISNULL is a built-in implemented in the database engine.
MSDN

COALESCE() can have multiple inputs and it will evaluate in order until one of them is not null such as COALESCE(Col1, Col2, Col3, 'N/A'). It's recommended to use this by MS instead of ISNULL()
ISNULL() can only have one input, however it's been shown to be slightly faster than COALESCE.

Related

Set the same value to columns if column is null and another value if column is not null using just nvl, decode or coalesce in Oracle

I need write select script that checks if column is null then shows "is null" value, when column is not null then shows "is not null" value in output. But I should use only nvl, decode or coalesce functions. Using another functionalities is not allowed.
Decode is quite simple:
select decode(column_name, null, 'is null',
'is not null'
) as result
from your_table
I don't see why (or how) should NVL and coalesce be involved here, their purpose is different. Maybe you could use them, but - that would be unnecessarily complicated.

SQL "IS NOT NULL" compensation for SAP HANA SQLScript

Actually I tried to run a is null SQL Statement on a SAP HANA Database using the SAP HANA Studio. This does not work because SQLScript has no is not null or is null function. My statement looks like:
Select *
From MSEG
Where KDAUF is null
Unfortunately it does not work. Does anybody know an alternative approach which is practicable using SAP HANA SQLScript? On the internet I found a hint to either use NULLIF or COALESCE. But I neither know how to use this function nor to adapt it to a working WHERE condition.
NULLIF ( expression , expression )
Returns the same type as the first expression.
NULLIF returns the first expression if the two expressions are not equal. If the expressions are equal, NULLIF returns a null value of the type of the first expression
WHERE IFNULL(KDAUF , comparison value) I never use this one
The other is coalesce where if the first vaLue is null, the second VALUE is returned:
WHERE VALUEa = COALESCE(KDAUF,valuea)
here, if kdaUf Is null, coalesce will will return valuea, the default if the first value is null. Since valuea = valuea, the where clause will be true, which is just another way of validating that KDAUF IS NULL
Try to use it this way
Select * from MSEG Where KDAUF **NE** ''

Should i use IIF and ISNULL to select a default-value?

Is this the best way to select default value from the table if selecting value is 0 or null?
DECLARE #value INT = 15
DECLARE #defaultValue INT = 12
SELECT IIF(ISNULL(#value,0) = 0, #defaultValue, #value)
Specify "best". Since IIF works only in SQL-Server i'd use CASE which is ANSI SQL standard and works in every(?) rdbms:
SELECT CASE WHEN ISNULL(#value,0) = 0 THEN #defaultValue ELSE #value END
Actually IIF is even translated to CASE:
IIF is a shorthand way for writing a CASE expression ...
The fact that IIF is translated into CASE also has an impact on other
aspects of the behavior of this function....
But the same is true for ISNULL which is also a SQL-Server function and could be replaced by COALECSE.
By the way, if you use ISNULL or COALESCE in a WHERE-clause, it prevents the query optimizer from using an index. So then you should prefer:
SELECT ...
FROM dbo.TableName
WHERE #value IS NOT NULL AND #value <> #value
However, i prefer ISNULL over COALESCE since the latter has an issue if it contains a sub-query. It is executed twice whereas ISNULL executes it once. Actually COALESCE is also translated into CASE. You can read about that issue here.
You can use the COALESCE. It evaluates the arguments in order and returns the current value of the first expression that initially does not evaluate to NULL. It is used for this purpose to get the first not null value.
SELECT COALESCE(#value,#defaultValue)
But keep in mind,
If all arguments are NULL, COALESCE returns NULL. At least one of the
null values must be a typed NULL.
You can also use the ISNULL but there is difference between both of them that is as listed below,
Comparing COALESCE and ISNULL
1) The ISNULL function and the COALESCE expression have a similar
purpose but can behave differently. Because ISNULL is a function, it
is evaluated only once. As described above, the input values for the
COALESCE expression can be evaluated multiple times.
2) Data type
determination of the resulting expression is different. ISNULL uses
the data type of the first parameter, COALESCE follows the CASE
expression rules and returns the data type of value with the highest
precedence.
3) The NULLability of the result expression is
different for ISNULL and COALESCE. The ISNULL return value is
always considered NOT NULLable (assuming the return value is a non-nullable one) whereas COALESCE with non-null parameters is
considered to be NULL. So the expressions ISNULL(NULL, 1) and
COALESCE(NULL, 1) although equivalent have different nullability
values. This makes a difference if you are using these expressions in
computed columns, creating key constraints or making the return value
of a scalar UDF deterministic so that it can be indexed as shown in
the following example.
If you are planning to use the sub queries in the expression to check for the NULL then you better of using the ISNULL as COALESCE will evaluate same query multiple times.
It can be a lot of arguments what is the best way and what it not, but
for me it is slightly more readable when using case syntax:
select case when #value is null then #defaultValue else #value end
You can use CASE statement.
SELECT CASE WHEN #value IS NULL THEN #defaultValue ELSE #value END
Or COALESCE expression
SELECT COALESCE(#value,#defaultValue)

SQL Statement to set NULL Values to initialized values

In SQL or T-SQL how can I go through a table and set fields that are NULL to empty strings if the type is textual and 0 if the fields are integer types.
Thanks for any help, I do not even know where to begin.
Well if it's just one table use a basic update query:
UPDATE MyTable
SET NumericColumn = ISNULL(NumericColumn,0),
StringColumn= ISNULL(StringColumn,'')
What you're suggesting would only work as a "one off".
If you always want those fields to be populated going forward you can set a default value on the table.
You can use IsNull function in T-SQL,
Syntax :
ISNULL ( check_expression , replacement_value )
The function coalesce( expression_1 , expression_2 , ... ) is also useful in this context.
It evaluates the specified expressions from left to right and returns the value of the first expression that evaluates to a value other than null, or null if all the specified expressions evaluate to null.
This can be useful, especially in conjunction with left joins and table rotations.

aggregate of an empty result set

I would like the aggregates of an empty result set to be 0. I have tried the following:
SELECT SUM(COALESCE(capacity, 0))
FROM objects
WHERE null IS NOT NULL;
Result:
sum
-----
(1 row)
Subquestion: wouldn't the above work in Oracle, using SUM(NVL(capacity, 0))?
From the documentation page about aggregate functions:
It should be noted that except for count, these functions return a null value when no rows are selected. In particular, sum of no rows returns null, not zero as one might expect. The coalesce function may be used to substitute zero for null when necessary.
So, if you want to guarantee a value returned, apply COALESCE to the result of SUM, not to its argument:
SELECT COALESCE(SUM(capacity), 0) …
As for the Oracle 'subquestion', well, I couldn't find any notion of NULLs at the official doc page (the one for 10.2, in particular), but two other sources are unambiguous:
Oracle SQL Functions:
SUM([DISTINCT] n) Sum of values of n, ignoring NULLs
sum aggregate function [Oracle SQL]:
…if a sum() is created over some numbers, nulls are disregarded, as the following example shows…
That is, you needn't apply NVL to capacity. (But, like with COALESCE in PostgreSQL, you might want to apply it to SUM.)
The thing is, the aggregate always returns a row, even if no rows were aggregated (as is the case in your query). You summed an expression over no rows. Hence the null value you're getting.
Try this instead:
select coalesce(sum(capacity),0)
from objects
where false;
Just do this:
SELECT COALESCE( SUM(capacity), 0)
FROM objects
WHERE null IS NOT NULL;
By the way, COALESCE inside of SUM is redundant, even if capacity is NULL, it won't make the summary null.
To wit:
create table objects
(
capacity int null
);
insert into objects(capacity) values (1),(2),(NULL),(3);
select sum(capacity) from objects;
That will return a value of 6, not null.
And a coalesce inside an aggregate function is a performance killer too, as your RDBMS engine cannot just rip through all the rows, it has to evaluate each row's column if its value is null. I've seen a bit OCD query where all the aggregate queries has a coalesce inside, I think the original dev has a symptom of Cargo Cult Programming, the query is way very sloooowww. I removed the coalesce inside of SUM, then the query become fast.
Although this post is very old, but i would like to update what I use in such cases
SELECT NVL(SUM(NVL(capacity, 0)),0)
FROM objects
WHERE false;
Here external NVL avoids the cases when there is no row in the result set. Inner NVL is used for null column values, consider the case of (1 + null) and it will result in null. So inner NVL is also necessary other wise in alternate set default value 0 to the column.