Not equal <> query excludes NULL values - mysql

I'm having a problem with some SQL queries that I cant figure out.
SELECT * FROM MasterList WHERE Requested <> "Yes";
If I run the above query on my table I get 60 records returned. However There should be close to 300. I think the issue is, some of the records are just blank in the Requested field and others are NULL. But I would have thought NULL would still count as not equal to "Yes" wouldnt it? If not, is there a way around that without having to go back and 'blank' all the null fields?

Nulls are not counted in comparison, if you want null values to be returned then you need to execute the following query:
SELECT * FROM MasterList WHERE Requested <> "Yes" OR Requested IS NULL;

<=>
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.
mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
-> 1, 1, 0
mysql> SELECT 1 = 1, NULL = NULL, 1 = NULL;
-> 1, NULL, NULL
in your case use:
SELECT * FROM MasterList WHERE not Requested <=> "Yes"

It happens because null <> 'Yes' expression evaluates to null, thus you should add a separate is null check to include records that meet this condition in your result set:
select * from MasterList where Requested <> "Yes" or Requested is null
P.S.: comparison of null with anything, even with null itself, always returns null.

I've struggled with the same issue and someone introduced me to the IS DISTINCT FROM construct. Very useful but not available for all DBMS!
SELECT * FROM MasterList WHERE Requested IS DISTINCT FROM "Yes";

Related

How null is treated using union and union all in mysql?

based on below statement
select null
union
select null
the output of the above statement is:
null
While this statement :
select null
union all
select null
Outputs:
null
null
As null <> null then how the value null is treated here and in which datatype it is considered
In standard SQL, UNION removes duplicate records, UNION ALL does not. Happlily your RDBMS is clever enough to figure out that NULL IS NULL, and eliminates duplicate rows when UNION is used.
NB : null = null is unknown, however null <> null is unknown as well. The only way to check for nullity is to use something like IS NULL.
SELECT case when null <> null then 1 else 0 end; --> yields : 0
SELECT case when null = null then 1 else 0 end; --> yields : 0
SELECT case when null IS null then 1 else 0 end; --> yields : 1
UNION is a set operator and involves checking for "duplicate rows". The specs define duplicate rows as "not being distinct". An excerpt from SQL-92 specs:
Two values are said to be not distinct if either: both are the null
value, or they compare equal according to Subclause 8.2, "<comparison
predicate>". Otherwise they are distinct. Two rows (or partial rows)
are distinct if at least one of their pairs of respective values is
distinct. Otherwise they are not distinct. The result of evaluating
whether or not two values or two rows are distinct is never unknown.
(emphasis mine). So, in this example:
select null
union all
select null
the two rows are considered duplicates of each other because the null values in first column are considered not distinct... i.e. same. And by definition UNION returns only one row from a set of duplicate rows.
I am considering that you know the difference between UNION (deduplicates results) and UNION ALL
select 'x' from dual where null is null \\results with x
In this case null is actually null. Which means union returns correct result (deduplicated)

Why does <> 'null' works in MySQL?

Hope the question is not too generic. Couldn't find anything on the site or in SQL documentation:
While coding, i tested this, and to my surprise it worked:
SELECT * FROM cal_entry WHERE cal_entry.parent_id <> 'null'
It actually shows the rows without the ones with NULL values (these are real NULL values in database, not strings with 'null' inside).
According to the docs, I should have used NOT NULL, of course. By the way, it doesn't work with = 'null', like it is correctly stated in the docs.
Can someone explain that?
You are selecting all rows where <> 'null' is true.
Comparing(equals or not-equals) to null is null, so if a row where cal_entry.parent_id is null, your condition will be false/null.
So your query gets all rows that are not null, nor contain the string 'null'.
(Note, you could just as well have written <>'something_else')
Assuming parent_id in an int column the query will return all non-null, non-zero rows:
SELECT *
FROM (
SELECT NULL AS parent_id UNION ALL
SELECT 0 UNION ALL
SELECT 1 UNION ALL
SELECT 2
) AS cal_entry
WHERE cal_entry.parent_id <> 'null'
-- returns 1 and 2 but not 0!
When comparing a number to string MySQL will convert the string to number. Some examples:
'null' becomes 0
'asdf' becomes 0
'1asdf' becomes 123
'1' becomes 1
Your query will behave like:
WHERE cal_entry.parent_id <> 0
this operator give you result of not equal to. ex. $var != null.
we write in mysql as <>. this is kind of validation that the value shoud never be equal to null.
When working with null following two statements should always be taken note of -
An expression can be null, but it can never be equal to null.
Two nulls are never equal to each other.
So, in your query wherever there is a comparison null<>null it returns true by second statement.
Also, always account the possibility that some rows might contain null -
Select * from cal_entry where cal_entry.parent_id!=10
This query would leave out the rows with null entries. Instead use -
Select * from cal_entry where cal_entry.parent_id!=10 or cal_entry.parent_id is null

Selecting rows with null in integer columns using mysql query

I have a table named 'datatablecoulmn' with the following columns.
now i want all rows where the column FkID is NULL.FkID is an integer field
i tried the following queries
SELECT * FROM `datatablecoulmn` WHERE `FkID`=NULL
SELECT * FROM `datatablecoulmn` WHERE `FkID`<1
SELECT * FROM `datatablecoulmn` WHERE `FkID`='null'
All of these returns empty rows .Any help?
In MySQL, NULL is considered as a 'missing, unknown value', as opposed to no value. 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.
Use IS NULL condition in your query and try like this
SELECT * FROM `datatablecoulmn` WHERE `FkID` IS NULL
For handling NULL values MySQL provides three operators
IS NULL: operator returns true if column value is NULL.
IS NOT NULL: operator returns true if column value is not NULL.
<=>: operator compares values, which (unlike the = operator) is true
even for two NULL values.
You can refer to these links for more
Link 1,Link 2,Link 3
You can't compare with NULL. So you gotta check for YourColumn IS NULL (or maybe YourColumn IS NOT NULL.
NULL is a value like infinity is a number. In other words, not at all. NULL is the absence of certain information.
For the same reason that NaN (not a number) in IEEE754 floating point is not equal to other instances (or even the same instance) of NaN, nothing in SQL is equal to NULL, including NULL.
That's something that may sound strange but, when you think of the purpose of NULL, that of specifying unknown or inappropriate values, it makes sense.
In order to see if a value is NULL, you have to therefore use something like:
where COLUMN_NAME is null
More details on working with NULL in MySQL can be found here.
Use something like:
SELECT * FROM `datatablecoulmn` WHERE `FkID` is NULL
NULL is a placeholder to say there is the absence of a value. Which is why you can only use IS NULL/IS NOT NULL as predicates for such situations and not = or != or <> which is used by values.
Here is another way to exclude the records with FkID is NOT NULL:
SELECT D1.*
FROM datatablecoulmn D1
WHERE NOT EXISTS (SELECT D2.*
FROM datatablecoulmn D2
WHERE D2.`FkID` IS NOT NULL)

Why MYSQL IN keyword not considering NULL values

I am using the following query:
select count(*) from Table1 where CurrentDateTime>'2012-05-28 15:34:02.403504' and Error not in ('Timeout','Connection Error');
Surprisingly, this statement doesnot include the rows having Error value as NULL.My intention is to filter only rows with Error value as 'Timeout' (or) 'Connection Error'. I need to give an additional condition( OR Error is NULL) to retrieve the correct result.
Why is MYSQL filtering out results with NULL values?
I thought that IN keyword would return a boolean result (1/0) and now i understand that some MYSQL keywords doesnt return boolean values,it might return NULL too....but Why is it treating NULL as special?
This :
Error not in ('Timeout','Connection Error');
is semantically equivalent to:
Error <> 'TimeOut' AND Error <> 'Connection Error'
Rules about null comparison applies to IN too. So if the value of Error is NULL, the database can't make the expression true.
To fix, you could do this:
COALESCE(Error,'') not in ('Timeout','Connection Error');
Or better yet:
Error IS NULL OR Error not in ('Timeout','Connection Error');
Or more better yet:
CASE WHEN Error IS NULL THEN 1
ELSE Error not in ('Timeout','Connection Error') THEN 1
END = 1
OR doesn't short-circuit, CASE can somehow short-circuit your query
Perhaps a concrete example could illustrate why NULL NOT IN expression returns nothing:
Given this data: http://www.sqlfiddle.com/#!2/0d5da/11
create table tbl
(
msg varchar(100) null,
description varchar(100) not null
);
insert into tbl values
('hi', 'greet'),
(null, 'nothing');
And you do this expression:
select 'hulk' as x, msg, description
from tbl where msg not in ('bruce','banner');
That will output 'hi' only.
The NOT IN is translated as:
select 'hulk' as x, msg, description
from tbl where msg <> 'bruce' and msg <> 'banner';
NULL <> 'bruce' can't be determined, not even true, not even false
NULL <> 'banner' can't be determined, not even true not even false
So the null value expression, effectively resolved to:
can't be determined AND can't bedetermined
In fact, if your RDBMS supports boolean on SELECT(e.g. MySQL, Postgresql), you can see why: http://www.sqlfiddle.com/#!2/d41d8/828
select null <> 'Bruce'
That returns null.
This returns null too:
select null <> 'Bruce' and null <> 'Banner'
Given you are using NOT IN, which is basically an AND expression.
NULL AND NULL
Results to NULL. So it's like you are doing a: http://www.sqlfiddle.com/#!2/0d5da/12
select * from tbl where null
Nothing will be returned
Because null is undefined so null does not equal null. You always have to explicitly handle null.
IN returns NULL if the expression on the left hand side is NULL. In order to get the NULL values, you have to do:
select count(*) from Table1 where CurrentDateTime>'2012-05-28 15:34:02.403504' and (Error not in ('Timeout','Connection Error') or Error is null);
IN returns a trivalent BOOLEAN (which accepts NULL as a value). NOT IN returns the trivalent negation of IN, and negation of NULL is a NULL.
Imagine we have a table with all numbers from 1 to 1,000,000 in id and this query:
SELECT *
FROM mytable
WHERE id IN (1, 2, NULL)
or its equivalent:
SELECT *
FROM mytable
WHERE id = ANY
(
SELECT 1
UNION ALL
SELECT 2
UNION ALL
SELECT NULL
)
The predicate returns TRUE for 1 and 2 and NULL for all other values, so 1 and 2 are returned.
In its oppposite:
SELECT *
FROM mytable
WHERE id NOT IN (1, 2, NULL)
, or
SELECT *
FROM mytable
WHERE id <> ALL
(
SELECT 1
UNION ALL
SELECT 2
UNION ALL
SELECT NULL
)
, the predicate returns FALSE for 1 and 2 and NULL for all other values, so nothing is returned.
Note that boolean negation not only changes the operator (= to <>), but the quantifier too (ANY to ALL).
#Michael Buen ' s answer was the right answer for my case, but let me simplify why.
#Michael says in his post:
Error not in ('Timeout','Connection Error');
is semantically equivalent to:
Error <> 'TimeOut' AND Error <> 'Connection Error'
Rules about null comparison applies to IN too. So if the value of Error is NULL, the database can't make the expression true.
And in [1] I found this sentence which confirms his most important statement for understanding why IN fails with NULL. In the specifications ("specs") in [1] you will: "If one or both arguments are NULL, the result of the comparison is NULL, except for the NULL-safe <=> equality comparison operator."
So yeah, the thing is that sadly Mysql gets lost in such a case. I think Mysql designers shouldn't have done this, because when I compare 2 to NULL, Mysql SHOULD be able to see they are DIFFERENT, and not simply throwing mistaken results. For example, I did:
select id from TABLE where id not in (COLUMN WITH NULLS);
then it throws EMPTY results. BUT. If I do
select id from TABLE where id not in (COLUMN WITH OUT NULLS);
it shows the right result. So when using the IN operator, you must filter out the NULLS. This is not a desired behavior for me as a user, but it's documented in the specifications in [1]. I think that languages and technology should be simpler, in the sense that you should be able to DEDUCE without the need of reading the specs. And truly, 2 is DIFFERENT from NULL, I should be the one in charge of controlling and taking care of mistakes of a higher level of abstraction, but MySQL SHOULD throw a FALSE result when comparing NULL with a specific value.
References for the specs: [1] http://dev.mysql.com/doc/refman/5.6/en/type-conversion.html
Sorry for posting twice in the same forum, but I want to illustrate another example:
I agree with #Wagner Bianchi in [2] in this forum when he says:
<< It’s very trick when dealing with data and subqueries>>
Moreover, this should NOT be the behavior, I think Mysql's designers are mistaken when they made this decision documented in [1]. The design should be different. Let me explain: You know that when comparing
select (2) not in (1, 4, 3);
you will get:
+----------------------+
| (2) not in (1, 4, 3) |
+----------------------+
| 1 |
+----------------------+
1 row in set (0.00 sec)
BUT if in the list you have at least one NULL then:
select (2) not in (1, NULL, 3);
throws:
+-------------------------+
| (2) not in (1, NULL, 3) |
+-------------------------+
| NULL |
+-------------------------+
1 row in set (0.00 sec)
This is pretty absurd.
We are not the first ones in getting confused by this. See [2]
References:
[1] http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_in
[2] http://blog.9minutesnooze.com/sql-not-in-subquery-null/comment-page-1/#comment-86954

NULL values not included in query result

Considering the following table:
create table inttest (
someint INT(10) NULL DEFAULT NULL
);
When I insert some random values
insert into inttest
(someint)
values
(1),(2),(3),(1),(2),(NULL);
and execute the query
select *
from inttest
where someint != 1;
MySQL returns 2,3,2 but not the NULL value. Is this correct? Should I extend my query with OR someint IS NULL or is it a bug in my MySQL installation?
Correct. Nothing is equal to NULL - including NULL. Or more formally, the result of evaluating NULL != 1 is UNKNOWN - and WHERE clause predicates have to evaluate to TRUE.
SELECT 1 != NULL;
-- Output: NULL
Comparison operators return TRUE, FALSE or NULL.
You're expecting NULL != 1 to give you TRUE but, sensibly, you get NULL for the comparison you make. This is because comparing anything with NULL is meaningless: NULL is not a value!.
Here's a cunning trick whereby you could get the NULL in the resultset if you still really want it. The trick relies on reversing the logic, then manually excluding the NULL possibility:
SELECT * FROM `inttest`
WHERE IF(`someint` = 1, FALSE, TRUE);
A more obvious approach might be:
SELECT * FROM `inttest`
WHERE `someint` != '1'
OR `someint` IS NULL;
You have to think of NULL as meaning UNKNOWN.
In your specific case, someint <> 1, you are asking the SQL engine to filter out anything that is not a 1. Since NULL is UNKNOWN, it could be a 1 but we will never know. Because of this, the SQL engine won't include it because it's not sure that it's not a 1.