How null is treated using union and union all in mysql? - 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)

Related

Checking value of a null field

Why does this return 0 records?
SELECT
*
FROM (
SELECT
null as 'first'
) a
WHERE
first <> 'TEST'
Null is not a word 'TEST'. I understand we could use Is Not Null but this came up because if I have a field that has
Null records that may not need to be excluded
Records with valid data that I want to exclude
Records with valid data I do not want to exclude
I'd rather just say "give me everything that isn't "TEST".
null is neither equal nor not equal to any other value, including null itself. Comparison operators return null when either operand is null:
select null <> 'TEST' returns null.
So does select null <> null.
You can use null-safe equals <=>, negated, instead:
where not(first <=> 'TEST')
or use coalesce:
where coalesce(first, '') <> 'TEST'

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

Not equal <> query excludes NULL values

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";

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)

MySQL mystery: Null value is not different from non-null string

Why is this query returning 0 rows?
select t.f1, t.f2
from (select null f1, 'a' f2 from dual) t
where t.f1<>t.f2;
This is a distilled version of a complex query I have. I want to compare two tables containing one-to-one related data and I want to select those rows that contain different values for certain fields. But also there can be the case where one row is missing in one of the tables. The LEFT JOIN correctly returns null values for these rows, but then, the WHERE clause is incorrectly (or unexpectedly) filtering these rows out.
Why -in this case- 'null' IS NOT DIFFERENT to any not null value (like 'a') ?
What is driving me crazy is that this
select t.f1, t.f2
from (select null f1, 'a' f2 from dual) t;
returns 1 row (as I expected) but this
select t.f1, t.f2
from (select null f1, 'a' f2 from dual) t
where t.f1=t.f2;
returns 0 rows !! So null is not equal to 'a' and null is not different to 'a' !!
Please... Can anybody explain this?
Exactly. NULL represents an unknown value, not any specific value (it is not the same as NULL in C, or nil in Ruby, etc.) In SQL, if you compare something to the unknown value, the result is also unknown. And you will not get the rows where WHERE condition is unknown.
Try this:
SELECT NULL <> 2;
and you will see NULL as result.
Try this:
SELECT * FROM t WHERE NULL;
and no rows will come out, even if the table t is huge.
If you really need what you said you wanted (and I am not advocating this), you can do something like this:
SELECT T.f1, T.f2
FROM (SELECT NULL f1, 'a' f2) T
WHERE ((T.f1 IS NULL OR T.f2 IS NULL)
AND (T.f1 IS NOT NULL OR T.f2 IS NOT NULL))
OR T.f1 <> T.f2
The concept of NULL is a common source of confusion for newcomers to SQL, who often think that NULL is treated as the other values.
This is not the case. Conceptually, NULL means "a missing unknown value" and therefore it is treated very differently.
What you are seeing is pretty easy to explain. Consider the following example:
CREATE TABLE mytb (id int, value int);
INSERT INTO mytb VALUES (1, 100);
INSERT INTO mytb VALUES (2, 200);
INSERT INTO mytb VALUES (3, NULL);
INSERT INTO mytb VALUES (4, 400);
The above means that for the row with id = 3, the value is "unknown". It could be 300, or it could be 100, or anything else.
Therefore when you request the following:
SELECT * FROM mytb WHERE value <> 100;
+------+-------+
| id | value |
+------+-------+
| 2 | 200 |
| 4 | 400 |
+------+-------+
2 rows in set (0.00 sec)
The row with id = 3 is not returned, because NULL <> 100 returns "unknown". We don't know if row id = 3 has a value of 100, so the expression does not return true. I doesn't return false either. It returns "unknown" (NULL).
The condition of the WHERE clause can only be satisfied when the expression is true. When you compare something to NULL, the expression can never be true. It will be "unknown".
SQL NULL does not work the way you would like it to work: http://en.wikipedia.org/wiki/Sql_null
In short, NULL = NULL is not true. NULL <> NULL is not true. NULL <> 1 is not true. And so forth.
NULL value is nothing, it can't be equal or not equal to something.
If you want to check if your value is null - use "IS NULL" statement:
select t.f1, t.f2
from (select null f1, 'a' f2 from dual) t
where t.f1 IS NULL
If you want to check if your values are equal or not equal - you can use COALESCE function on nullable columns:
select t.f1, t.f2
from (select null f1, 'a' f2 from dual) t
where COALESCE(t.f1, '')<>COALESCE(t.f2, '');
Try to do this query:
select * from dual where NULL = NULL
It returns 0 rows. That's because to compare a value with null you have to do IS NULL or IS NOT NULL, otherwise it will return false.