SELECT IFNULL(NULL, 'Replaces the NULL')
--> Replaces the NULL
SELECT COALESCE(NULL, NULL, 'Replaces the NULL')
--> Replaces the NULL
In both clauses the main difference is argument passing. For IFNULL it's two parameters and for COALESCE it's multiple parameters. So except that, do we have any other difference between these two?
And how it differs in MS SQL?
The main difference between the two is that IFNULL function takes two arguments and returns the first one if it's not NULL or the second if the first one is NULL.
COALESCE function can take two or more parameters and returns the first non-NULL parameter, or NULL if all parameters are null, for example:
SELECT IFNULL('some value', 'some other value');
-> returns 'some value'
SELECT IFNULL(NULL,'some other value');
-> returns 'some other value'
SELECT COALESCE(NULL, 'some other value');
-> returns 'some other value' - equivalent of the IFNULL function
SELECT COALESCE(NULL, 'some value', 'some other value');
-> returns 'some value'
SELECT COALESCE(NULL, NULL, NULL, NULL, 'first non-null value');
-> returns 'first non-null value'
UPDATE: MSSQL does stricter type and parameter checking. Further, it doesn't have IFNULL function but instead ISNULL function, which needs to know the types of the arguments. Therefore:
SELECT ISNULL(NULL, NULL);
-> results in an error
SELECT ISNULL(NULL, CAST(NULL as VARCHAR));
-> returns NULL
Also COALESCE function in MSSQL requires at least one parameter to be non-null, therefore:
SELECT COALESCE(NULL, NULL, NULL, NULL, NULL);
-> results in an error
SELECT COALESCE(NULL, NULL, NULL, NULL, 'first non-null value');
-> returns 'first non-null value'
Pros of COALESCE
COALESCE is SQL-standard function.
While IFNULL is MySQL-specific and its equivalent in MSSQL (ISNULL) is MSSQL-specific.
COALESCE can work with two or more arguments (in fact, it can work with a single argument, but is pretty useless in this case: COALESCE(a)≡a).
While MySQL's IFNULL and MSSQL's ISNULL are limited versions of COALESCE that can work with two arguments only.
Cons of COALESCE
Per Transact SQL documentation, COALESCE is just a syntax sugar for CASE and can evaluate its arguments more that once. In more detail: COALESCE(a1, a2, …, aN)≡CASE WHEN (a1 IS NOT NULL) THEN a1 WHEN (a2 IS NOT NULL) THEN a2 ELSE aN END. This greatly reduces the usefulness of COALESCE in MSSQL.
On the other hand, ISNULL in MSSQL is a normal function and never evaluates its arguments more than once. COALESCE in MySQL and PostgreSQL neither evaluates its arguments more than once.
At this point of time, I don't know how exactly SQL-standards define COALESCE.
As we see from previous point, actual implementations in RDBMS vary: some (e.g. MSSQL) make COALESCE to evaluate its arguments more than once, some (e.g. MySQL, PostgreSQL) — don't.
c-treeACE, which claims it's COALESCE implementation is SQL-92 compatible, says: "This function is not allowed in a GROUP BY clause. Arguments to this function cannot be query expressions." I don't know whether these restrictions are really within SQL-standard; most actual implementations of COALESCE (e.g. MySQL, PostgreSQL) don't have such restrictions. IFNULL/ISNULL, as normal functions, don't have such restrictions either.
Resume
Unless you face specific restrictions of COALESCE in specific RDBMS, I'd recommend to always use COALESCE as more standard and more generic.
The exceptions are:
Long-calculated expressions or expressions with side effects in MSSQL (as, per documentation, COALESCE(expr1, …) may evaluate expr1 twice).
Usage within GROUP BY or with query expressions in c-treeACE.
Etc.
Differences in SQL-Server:
There is no IFNULL() function but a similar ISNULL()
ISNULL takes only 2 parameters whereas COALESCE takes variable number of parameters
COALESCE is based on the ANSI SQL standard whereas ISNULL is a proprietary TSQL function
Validations for ISNULL and COALESCE is also different. For example, NULL value for ISNULL is converted to int, whereas for COAELSCE you have to provide a type. Ex:
ISNULL(NULL,NULL) : is int.
COALESCE(NULL,NULL) : will throw an error.
COALESCE(CAST(NULL as int),NULL) : is valid and returns int.
Data type determination of the resulting expression – ISNULL uses the first parameter type, COALESCE follows the CASE expression rules and returns type of value with highest precedence.
ifnull can only replace a null value of the first parameter. Whereas coalesce can replace any value with another value. With coalesce in standard SQL you can have many parameters transforming many values.
EDIT the example according to comments below.
Example: coalesce(null, null, null, 'b*', null, 'null*')
returns 'b*' and it is not possible to do with ifnull.
This db2 SQL will not work with COALESE, I will not see any rows retrieved.
Since I used IFNULL it is working as expected
select a.mbitno ,a.mbstqt,ifnull(b.apr,0)
from
(
select mmstcd,mbstat,mbfaci,mbwhlo,mbitno,mbstqt,MBALQT from libl.mitbal inner join libl.mitmas on
mmcono=mbcono and mmitno=mbitno
where mbcono=200 and mbstat in ('20','50') and mmstcd>0
)
as a left join
(
select mlfaci,mlwhlo,mlitno,mlstas,sum(mlstqt) as APR from libl.mitloc where mlcono=200 and mlstas='2'
group by mlfaci,mlwhlo,mlitno,mlstas
)
b on b.mlfaci=a.mbfaci and b.mlwhlo=a.mbwhlo and b.mlitno=a.mbitno
where a.mbitno in 'GWF0240XPEC' and a.mbstqt>0 and a.mbstqt<>ifnull(b.apr,0)
Related
I am new to COALESCE function in REDSHIFT. I ran below four queries in mysql and Redshift.
1st and 2nd query executed as expected in both mysql and redshift. But for 3rd and 4th query I am getting two different results in mysql and Redshift. How does this behave?
select COALESCE(null,null,1) -> 1
select COALESCE(null,null,'John') -> 1
select COALESCE(null,null,1,'John') -> (Redshift : error , mysql:1)
select COALESCE(null,null,'John',1) -> (Redshift: error, mysql:John)
Also this query should give error in mysql but it has succeeded
Any help is appreciated
Amazon Redshift Database Developer Guide claims:
An NVL expression is identical to a COALESCE expression. NVL and
COALESCE are synonyms.
Syntax
NVL | COALESCE ( expression, expression, ... )
An NVL or COALESCE expression returns the value of the first expression
in the list that is not null. If all expressions are null, the result
is null. When a non-null value is found, the remaining expressions in
the list are not evaluated.
This type of expression is useful when you want to return a backup
value for something when the preferred value is missing or null. For
example, a query might return one of three phone numbers (cell, home,
or work, in that order), whichever is found first in the table (not
null).
If you obtain the error this may mean that the returned value datatype do not match the datatype of recordset field or any another structure which must accept the returned value.
PS. Will you show error messages?
Though it is not written in the documentation, but coalesce works on the compatible data types. Integer and varchar cannot be compared.
The error becomes more evident when you provide column name instead of hard-code values. Try executing this:
select coalesce(integer_column, varchar_column) from a_table;
You would get an error saying something like this:
coalesce types integer and varchar cannot be matched.
I have complex SQL-Statements with group_concat and i need sometimes to convert the value. So i use something like this (Its an example):
SELECT IF(1=1,CAST(TEST AS CHAR),CAST(TEST AS UNSIGNED))
FROM(
SELECT '40' as TEST
UNION
SELECT '5' as TEST
UNION
SELECT '60' as TEST
) as t1
ORDER BY TEST ASC;
Should return CHAR, returns CHAR.
SELECT IF(1=0,CAST(TEST AS CHAR),CAST(TEST AS UNSIGNED))
FROM(
SELECT '40' as TEST
UNION
SELECT '5' as TEST
UNION
SELECT '60' as TEST
) as t1
ORDER BY TEST ASC;
Should return UNSIGNED, returns CHAR
So the result of IF condition is always a CHAR and need to be CAST.
How i can resolve the problem?
MySQL tries to figure out the column type just by parsing the SQL, not based on runtime conditions like the way an IF() expression goes. While your example allows the result of the IF() to be determined before actually processing any rows, this is not true in general and MySQL doesn't perform this optimization.
It just sees that the IF() can return either UNSIGNED or CHAR, and figures out a common type that both can be converted to safely. This is CHAR.
This is explained in the documentation:
The default return type of IF() (which may matter when it is stored into a temporary table) is calculated as follows:
If expr2 or expr3 produce a string, the result is a string.
If expr2 and expr3 are both strings, the result is case-sensitive if either string is case sensitive.
If expr2 or expr3 produce a floating-point value, the result is a floating-point value.
If expr2 or expr3 produce an integer, the result is an integer.
COALESCE is an SQL function that returns the first non-NULL expression among its arguments. So in the following statement...
SELECT USER.user_id,
USER.firstname,
USER.lastname,
...
COALESCE(EMPLOYEE.title, '') title,
...
FROM USER
... it is basically saying that if EMPLOYEE.title is NULL, then return and use '' instead. Is my understanding correct?
Let's say that EMPLOYEE.title equals 'CEO'. If we plug this into the COALESCE function, our query would look something like:
SELECT COALESCE('CEO', '') sub_sector;
If we ran it, we would get 'CEO'. Now let's say that EMPLOYEE.title is NULL. If we plug that into the COALESCE function, our query would look something like:
SELECT COALESCE(NULL, '') sub_sector;
If we run that, we will get '' since COALESCE returns the first non-null value in its argument list. Since the first value is NULL, it will then check the next value, '', which is not NULL, so it will return it.
In the case of your query, if the field EMPLOYEE.title has a NULL value, the COALESCE function will return ''.
One of my columns in the table contains 'NULL' values and I would like to replace them with certain values.
I looked at this post: Replace nulls values in sql using select statement? and followed the answer.
My sql statement:
Select ifnull(`option`, 'MCQ') as `option`
from question_table
This statement returns me the columns there are already with 'MCQ', but the 'NULL' values are not replaced yet.
Need some guidance to change this.
If you want to change the data, you need an update:
update question_table
set option = 'MCQ'
where option is null;
A select statement does not change the database.
If you want to update the table use Gordon's answer, but maybe you just want to return a replacement value for NULL in the SELECT, you can use COALESCE:
SELECT COALESCE(`option`, 'MCQ') as `option`
FROM question_table
This selects MCQ for every option-value that is NULL.
Another way is using CASE:
SELECT CASE WHEN `option` IS NULL THEN 'MCQ' ELSE `option` END as `option`
FROM question_table
'NULL' is a string, NULL is a special value that means "unknown/unavailable". They are totally different things.
MySQL function IFNULL() handles NULL values (they cannot be compared using the regular comparison operators). You can use the regular comparison operators (=, <>) to work with strings, even when they are 'NULL'.
If your query produces 'NULL' values in the result set it means the values in the database are not NULL but strings ('NULL').
In this case the query you need is:
SELECT IF(`option` = 'NULL', 'MCQ', `option`) AS `option`
FROM question_table
I'm selecting the max of a column from a table. But there is one problem: if there are no rows in the table, it returns null.
I want to use a function which will return a certain value if the result is null. For example with Oracle there is the NVL function which gives a certain value if the column is null. Is there an equivalent function in MySQL ?
Use coalesce:
select coalesce(column_name, 'NULL VALUE') from the_table
or you can use IFNULL(expr1,expr2)
If expr1 is not NULL, IFNULL() returns expr1; otherwise it returns expr2.
select IFNULL(column_name, 'NULL VALUE') from the_table;
taken from:
https://dev.mysql.com/doc/refman/8.0/en/flow-control-functions.html#function_ifnull