null not in exhaustive list - sql

I have a row full of 1, 2, 3 and null. Why don't there two return the same result:
select * from foo where foobar not in (1, 2, 3);
select * from foo where foobar is not null;
The first one returns empty set, while second one works as advertised. Now I'm a bit confused :-D Is there some kind of "NULL in SQL for newbies" document anywhere? :-D
(I'm using Oracle, if that matters)

It's because your first statement is being evaluated like this:
select * from foo
where foobar <> 1 and foobar <> 2 and foobar <> 3
"null <> 1" evaluates to null, not true/false, so nothing is returned.

Any boolean operation involving NULL always fails. If foobar is NULL then:
- The test = 1 fails.
- But <> 1 also fails.
This means that NULL not in (1, 2, 3) always fails.
It's a peculiarity of NULL Logic that takes getting used to at first. NULL can be taking to mean Unknown. Which means it might be 1, an might might not. It's indeterminate.
So when you ask is NULL in the list (1, 2, 3) the answer is I can't tell, it's indeterminate. So rather than being TRUE or FALSE the answer itself is NULL.
And because NULL isn't TRUE, the row has failed the test.

not in is not opposite of in
for detail check http://jonathanlewis.wordpress.com/2007/02/25/not-in/

Related

Coalesce different with case

i get confused in learning coalesce, I am new to sql.
example :
select case when value is null then 1
else value end as value
from table
and
select coalesce(value, 1)
from table
and in the tutorial I see in internet there are like
select coalesce (arg_1, arg_2, arg_3)
if I make
select coalesce(value, 1, 2)
how I can make to show the return value is 2?
Your query with the first and second will reproduce the same result, But you are wrong understanding the Coalesce concept.
Definition in Documentation Postgresql
The COALESCE function returns the first of its arguments that is not
null. Null is returned only if all arguments are null.
So it means it will return the first argument that is not null, it is not like case statement with condition like true or false
Let's try with example :
select coalesce(null, 1)
It will return 1 like the query you show, or
select coalesce(null, null, 1)
It will return 1 too even 1 in the arg_3 and how about there are 2 value not null?
select coalesce(null, 1, 2)
It will return 1. Why? Like in the documentation said "returns the first of its arguments that is not null" so when there is 2 value not null the first argument have not null value will get return
You can check this demo and try :
Demo<>Fiddle
Hope it helps

"!="/NOT perhaps not working properly in SQLite

I have a table with about a hundred rows. It has a column is_gallery that contains either 1, 0, or NULL. If I do...
SELECT * WHERE is_gallery != 1
or
SELECT * WHERE NOT (is_gallery = 1)
it excludes the rows where is_gallery is null. I can manage to get a proper response if I do
SELECT * WHERE (is_gallery = 0 OR is_gallery is null)
But shouldn't the "!=" or NOT work? Isn't there a way to just return the rows where is_gallery doesn't equal 1 without testing for every other possibility?
You can use the IS and IS NOT operators instead of = and !=. These treat NULL like a normal value.
SELECT * FROM yourTable WHERE is_gallery IS NOT 1
The best thing to use is coalesce as in:
SELECT *
WHERE coalesce(is_gallery,0) != 1;
what coalesce does, is replaces any null value in that column with the second parameter. In the example above, any nulls in the "is_gallery" column will be replaced with 0 before it is compared with 1. So will of course return true.
On NULL realize that a NULL value isn't equal to ANYTHING - not even NULL itself. It cannot be compared - so when "comparing", it always will return FALSE. On NULL, it has a special operator which is "IS NULL" or "IS NOT NULL"

NULL IN (1,2,NULL) returns false

Why does this SQL-statement return 0?
SELECT CASE WHEN NULL IN (9,1,NULL) THEN 1 ELSE 0 END
SQL is based on three-valued logic, where there are three truth values: TRUE, FALSE, and UNKNOWN. The special NULL value is a placeholder for "missing data" and if you compare something, anything, with missing data the result is unknown.
For example, is <missing data> equal to <missing data>? It's impossible to know, so the result is UNKNOWN.
In this particular case, you are trying to find out if <missing data> is in a given list: since the data is missing, it's impossible to know if it's in the list, and the query returns 0.
SELECT CASE WHEN NULL IN (9,1,NULL) THEN 1 ELSE 0 END
I don't know what RDBMS you are using since some of them has configuration on how NULL will be treated.
NULL IN (9, 1, NULL)
can be written as
(NULL = 9) OR (NULL = 1) OR (NULL = NULL)
and not of them were TRUE nor FALSE. They are all NULL. Since there are only two paths in the CASE statement, it falls under ELSE block.
It depends on how NULL is treated in the specific server.
For instance in SQL SERVER you may set ANSI_NULLS off and have it return 1:
SET ANSI_NULLS OFF
SELECT CASE WHEN NULL IN (9,1,NULL) THEN 1 ELSE 0 END
For further info you should read the remarks section of SET ANSI_NULLS
Because you can't compare null values using comparison operators. You can only use is null or is not null or using functions like COALESCE(), ISNULL(). For example
SELECT CASE WHEN COALESCE(NULL,-1) IN (9,1,-1) THEN 1 ELSE 0 END
Null mean not defined.
NUll object is not equal to other NULL
NULL==1 return false
NUll==2 return false
NULL==NULL return also false

How does 'in' clause works in oracle

select 'true' from dual where 1 not in (null,1);
when we execute this which will result nothing
what my question is:
is the above query is logically equivalent to
select 'true' from dual where 1 != null and 1 != 1;
which will result nothing just as above statement
Please clarify?
Correct (but note that IN is an operator, not a clause and it works like this in SQL in general, not only for Oracle).
where 1 not in (null,1)
is equivalent to:
where 1 != null and 1 != 1
which should really be written as:
WHERE 1 NOT IN (NULL, 1)
and
WHERE 1 <> NULL AND 1 <> 1
which is the same as:
WHERE (1 <> NULL) AND (1 <> 1)
which evaluates to:
WHERE UNKNOWN AND FALSE
and further as:
WHERE FALSE
So, it correctly returns no rows.
Notice that if you had WHERE 1 NOT IN (NULL, 2), it would evaluate to WHERE UNKNOWN (left as an exercise) and no rows would be returned either.
The issue of your script in comparing with NULL value. You should use
column is null and column = 1
Actually NULL is an undefined value. Any comparation with NULL gives neither True nor False but NULL. Even NULL = NULL
That's why your 1 not in (null,1) doesn't work.
Yes they are.
select something from table where column not in (1,2,3);
is equivalent to
select something from table where column != 1 and column != 2 and column != 3;
The IN statement is a collection of OR statements, while NOT IN is a collection of AND statements - but it is also not equal to.
So the NOT IN is equivalent to:
1 <> NULL
AND 1 <> 1
AND ...
While the IN would be equivalent to:
1 = NULL
OR 1 = 1
OR ...
Note that having NULL in the collection will not work, due to the quirky nature of NULL.
Yes. It is correct. Also NULL values should be compared with IS NULL

Difference between MySQL IS NOT NULL and != ''

Is there any difference between MySQL
IF (myText IS NOT NULL) THEN
and
IF (myText != '') THEN
Yes there is a big difference between a NULL value and a blank/empty value.
Here's one resource that describes the differences.
When myText IS NULL:
myText IS NOT NULL evaluates to FALSE
myText != '' evaluates to NULL (which essentially behaves the same as FALSE would in this specific case you wrote)
However, you should not get into the habit of treating them the same, since most of the time they will behave differently: For example:
Assume you have a table tbl:
id text
1 NULL
2
3 abc
Note: 1 contains a NULL value, and 2 contains an empty string ('').
If you run the following query:
SELECT * FROM tbl WHERE text != ''
... it will return record 3.
If you run the following query:
SELECT * FROM tbl WHERE text IS NOT NULL
... it will return records 2 and 3.
Yes there is a difference.
In simple words, myText IS NOT NULL specifies that myText is having some value which could be '' too.
Where as myText != '' specifies that it returns TRUE, if myText does NOT contain an empty string.
There is a difference. If the default value of a column is "NULL", then if no data has been set for a field, it is truly null. However, if the value of a field has been updated as '', it is not NULL, rather it is empty.
See here for more information Link