I am just curious - I know about NULL safe equal operator <=>, but is there some NULL safe NOT equal operator? Or I have to always use something like this:
(tab.id != 1 OR tab.id IS NULL)
or someone prefers
!(tab.id <=> 1)
I found that NOT (NULL <=> 1) works and I think it is also ISO standard compliant, but is cumbersome. A better way to show using column names would be like this: NOT (tbl.col1 <=> 1)
COALESCE(tab.id, 0) != 1
Can be used here if you like it. I goes through the parameters, and returns the first value that isn't NULL. In this case if it's NULL, it will compare 0 != 1. Although it may use more signs, it's still easier to manage instead of being forced to always have opposite "booleans" as a solution in those cases.
Read documentation for COALESCE()
Now MySQL does not have a NULL-safe not equal operator.
Using MySQL the most universal solution is:
!(tab.id <=> 1)
or
NOT tab.id <=> 1
because it will work properly if even in place of 1 you will use NULL.
If you know that the RHS of the comparison IS NOT NULL:
COALESCE(tab.id != 1, 1)
Or
COALESCE(tab.id != 1, TRUE)
will give you the correct result.
Whether this is better more readable than:
(tab.id != 1 OR tab.id IS NULL)
Is debatable..
I'd also be tempted to filter out the NULL logic first with comparisons, so I don't have to think about them! I'd probably write your first equation as:
(tab.id IS NULL OR tab.id != 1)
Performance will depend on prevalence of NULLs however.
Related
Sorry, this is probably a really frequent question, but I really don't know how to phrase a google search that finds it.
SELECT * FROM table where textfield != "Word";
This ignores all rows where the textfield has the string "Word" - but it also ignores all rows where textfield is NULL. Why?
What is the correct way of selecting ALL rows (even NULLS), except rows with a specific string in a text field?
Almost all comparisons with NULL return NULL (the most common excepts are IS NULL and IS NOT NULL). And in WHERE clauses, NULL is treated the same as "false" -- that is, the rows are filtered.
MySQL offers a NULL-safe comparison operator. You can use:
where not textfield <=> 'Word'
<=> returns true or false -- never NULL -- so it does what you expect.
Let me add: The SQL Standard has a NULL-safe operator. So, in Standard SQL, this would be:
where textfield is distinct from 'Word'
However, not many databases support the standard syntax -- yet.
You need to tell the database to include the rows where textfield is NULL:
SELECT *
FROM table
WHERE textfield != 'Word' OR
textfield IS NULL
In a relational database any direct comparison to NULL (using comparison operators such as =, <> or !=, <, >, <=, or >=) will return NULL or UNKNOWN (depending on the database). This is intentional and by design - but it does make it a bit awkward sometimes. If you want NULLs included you need to specify that.
In some databases you can use the NVL or COALESCE functions to provide a "default value" to replace NULLs with, as in:
SELECT *
FROM table
WHERE NVL(textfield, 'X') != 'Word'
or
SELECT *
FROM table
WHERE COALESCE(textfield, 'X') != 'Word'
COALESCE is the ANSI version, allows multiple arguments, and is the preferred solution. For example, if you want to return textfield, but if was NULL you wanted to return text2, and then if text2 was also NULL you wanted to return X you could use
SELECT *
FROM table
WHERE COALESCE(textfield, text2, 'X') != 'Word'
Just wondering, how this query will be handled by MySQL, will sum() calculated twice if sum(credits) != NULL or does MySQL has optimization in place for such queries.
select if(sum(credits)=NULL, 0, sum(credits)) from ......
Thanks
If won't work. The first condition is always false. The correct way to compare to NULL is IS NULL, not =.
Just use this construct:
select coalesce(sum(credits), 0)
Using IF
SELECT IF(sum(credits) IS NULL, 0 ,sum(credits)) .....
IF(expr1,expr2,expr3)
If expr1 is TRUE (expr1 <> 0 and expr1 <> NULL) then IF() returns expr2; otherwise it returns expr3. IF() returns a numeric or string value, depending on the context in which it is used
Using IFNULL
SELECT IFNULL(sum(credits), 0) .....
Using COALESCE
SELECT COALESCE(sum(credits), 0) .....
Refer : MySQL Control Flow Functions
This is something we shouldn't worry about. With SQL we tell the DBMS what to do, not how to do it.
It is very, very likely that the DBMS will compute sum(credits) only once. It would seem rather stupid if not. However, this is not dictated by the SQL standard, so the DBMS programmers are free to choose how to code this. They could write the DBMS such that sum(credits) is computed twice. We cannot know whether they did or not, but as mentioned it is not likely and we shouldn't worry about it either.
These two MySQL functions do the same thing:
IFNULL(column_name, 'test') = 'test'
or
NULLIF(column_name, 'test') IS NULL
Which one is more efficient?
Purpose of NULLIF and IFNULL is not same, so performance comparison does not make any sense.
NULLIF is used to return null if the expression has a specific value, whereas IFNULL is used to return text if expression is null.
Example:
SELECT IFNULL(field,'empty') from table1;
Since null does not make much sense to end user.
insert into table1 (field) values (nullif(field,'empty'));
Since null has a special meaning in database.
They are both as efficient as each other - the functions have about the same overhead as each other.
But this is more efficient than either:
(column_name is null
or column_name = 'test')
Because the function doesn't need to be invoked.
You may find putting the more commonly encountered test first improves performance.
With questions like this, the simplest and more reliable way to discover relative performance is to just try them and compare query timings. Make sure you have production-sized and realistic-valued datasets so the test is fair.
they are used for different purpose, performance comparison doesn't make any sense.
select if(a,b,c); # a ? b : c # if a!=0 and a is not null then b else c
select ifnull(a,b); # a ? a : b # if a is not null then a else b
select nullif(a,b); # a=b ? null : a # if a=b then null else a
http://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html
I have a column called CODE in a MySQL table which can be NULL. Say I have some rows with CODE='C' which I want to ignore in my select result set. I can have either CODE=NULL or CODE!='C' in my result set.
The following query does not return a row with CODE as NULL:
SELECT * from TABLE where CODE!='C'
But this query works as expected and I know it is the right way to do it.
SELECT * from TABLE where CODE IS NULL OR CODE!='C'
My question is why does having only CODE!='C' does not return rows where CODE=NULL? Definitely 'C' is not NULL. We are comparing no value to a character here. Can someone throw some light as why it doesn't work that way?
In MySQL, NULL is considered as a 'missing, unknown value', as opposed to no value. Take a look at this MySQL Reference on NULL.
Any arithmetic comparison with NULL does not return true or false, but returns NULL instead., So, NULL != 'C' returns NULL, as opposed to returning true.
Any arithmetic comparison with 'NULL' will return false. To check this in SQL:
SELECT IF(NULL=123,'true','false')
To check NULL values we need to use IS NULL & IS NOT NULL operator.
Based on my tests and the documentation here: http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html
You can compare null and get a boolean result using <=>
NOTE: it looks like NOT EQ operator, but it's EQ operator
For example:
select x <=> y;
or
select #x <=> #y;
This also compares string vs null, string vs string, etc.
In SQL, the NULL value is a special value, not comparable with any other one.
The result of a direct comparison with a NULL is always NULL, although (unfortunately) you may find FALSE in some implementation.
To test a null value you should use IS NULL and IS NOT NULL.
SELECT *
FROM `table_name`
WHERE IFNULL(`column_name` != 'C', TRUE)
The specified problem can also appear in joins and the above answers aren't particularly helpful. The way I prefer to do it is by coalescing to otherwise impossible value. For example, this
select foo from bar
inner join baz on bar.x = baz.y
won't work if bar.x and baz.y are both nulls (join won't bring results). The workaround is to use e.g.
select foo from bar
inner join baz on coalesce(bar.x, -1) = coalesce(baz.y, -1)
where -1 is "impossible" value meaning it can never appear in the data set.
select * from user where application_id='1223333344' and name is null;
I use:
SELECT * from TABLE where NOT(CODE <=> 'C')
I've recently changed all my where conditions to use <=> instead of = because I need to check against nulls. Are there any performance concerns?
There is no real performance impact here is a test to verify for yourself
mysql> SELECT BENCHMARK(1000000, (SELECT SQL_NO_CACHE userId FROM Activity WHERE userId<=>42459204 LIMIT 1));
Make sure that you need to use <=>
NULL-safe equal. This operator
performs an equality comparison like
the = operator, but returns 1 rather
than NULL if both operands are NULL,
and 0 rather than NULL if one operand
is NULL.
If you just need to check the rvalue do
col=CONST AND CONST IS NOT NULL
or t1.col=t2.col
<=> is basically a shortcut to include OR (Val1 IS NULL AND Val2 IS NULL) or IS NOT DISTINCT FROM
It is an additional operation but the difference should be negligible unless you are SELECTing the data to be compared because otherwise the first SELECT returning NULL doesn't need to execute the second SELECT because the standard equality operator = will always yield false.
As #Dathan noted, make sure this is actually when you intend to do.