Table of contents
Case 1: When in contains null in the filter condition
Case 3: When not in contains NULL
0 data preparation
create table t as
select '张三' as name,1 as class
union all
select '李四' as name,1 as class
union all
select '王五' as name,2 as class
union all
select '老六' as name,null as class
union all
select '陈七' as name, 4 as class
union all
select '赵八' as name, 5 as class
union all
select '孙九' as name, 5 as class
1 analysis
The original table data is as follows:
Case 1: When in contains null in the filter condition
select * from t where class in (null,'1')
in is equivalent to or, and the judgment of null is not is null but equal, so the judgment of NULL is always false
select * from t where class ='1' or class =null
If you want to get the result of NULL, you must convert the value of NULL, you can use the following SQL
select * from t where coalesce(class,'null') in ('null','1')
Conclusion: When in contains null, no NULL result will be obtained
Case 2: When there is NULL in the main table, NULL will be ignored when not in is used and not followed by a subquery, and NULL cannot be matched, that is, no NULL records can be queried
select * from t where class not in ('1','2')
Case 3: When not in contains NULL
select * from t where class not in ('1','2',null)
not in is equivalent to the and condition, as long as there is one false, then all are false. We know that in not in is judged by the equal sign (=), and is not null will not be used for null, so the above is rewritten as:
select * from t where class !='1'and !='2'and !=null
The result is as follows:
Since the interpretation is not equal to NULL, it will always be false, and all the conditional judgments are false, and where is false,
then the result will return nothing. For the case of filtering null, you can rewrite it like this, convert null to the string 'null', The SQL is as follows:
select * from t where coalesce(class,'null') not in ('1','2','null')
Case 4: If not in is followed by a subquery, special attention should be paid to the selected field containing NULL values
The following SQL:
select *
from t
where class not in (
select class
from t t1
where coalesce(t1.class, 'null') in (1, 2, 'null'))
The final returned result is empty because the subquery contains NULL values. Special attention must be paid to this situation. When not in contains subqueries, if the result contains NULL values, no results will be found. At this time It should be necessary to actively filter out NULL values in subqueries.
create table t1 as
select 1 as class
union all
select 2 as class
union all
select 3 as class
union all
select 4 as class
union all
select null as class
union all
select null as class
select *
from t
where class not in (
select class
from t1
)
end result is empty
The correct way to write it is as follows:
select *
from t
where class not in (
select class
from t1
where class is not null
)
Or use not exists instead of not in. Note that the uses of the exists function and in are different.
exists is actually a high-order predicate. The so-called high-order means that the number of input rows is often multiple rows, a set, which is different from other predicate judgments. The input value of other predicates is generally a scalar value (single value) , we know that the parameter of EXISTS is a collection of row data, the reason for saying this is because no matter what column is selected in the subquery, it is the same for EXISTS. In the subquery of EXISTS, the list of SELECT clauses can be written in the following three ways.
select *
from t
where NOT EXISTS (
select t1.class
from t1
where t.class=t1.class
)
====================
select *
from t
where NOT EXISTS (
select 1
from t1
where t.class=t1.class
)
====================
select *
from t
where NOT EXISTS (
select *
from t1
where t.class=t1.class
)
The result is as follows:
OK
t.name t.class
老六 NULL
孙九 NULL
赵八 5
Time taken: 39.269 seconds, Fetched: 3 row(s)
Use a diagram to summarize the difference between general predicates and EXISTS
There is a problem here, the results in our subquery are as follows:
select class
from t1
where class is not null
So is the above result equivalent to the following SQL?
select * from t where class not in (1,2,3,4)
Execute the above SQL: we get the following results
Obviously, the two SQLs are not equivalent. That is to say, when there is a subquery in not in, the NULL in the main table will not be ignored, and the result of NULL in the main table can be obtained. When the not in is a constant value, the NULL in the main table The NULL is ignored, which is a bit of a pitfall.
If you have to filter out NULL values, you can write as follows
select *
from t
where coalesce(class,'null') not in (
select coalesce(class,'null')
from t1
)
2 Summary
- (1) When there is NULL in the filter condition in in, regardless of whether in is followed by a constant or NULL in the main table of the subquery, it will not be filtered. At this time, the COALESCE() function can be used to convert the NULL value for filtering.
- (2) When there is NULL in the main table and not in is used, if not in is followed by a constant, there will be no NULL in the filtered result, and the NULL value will be ignored. If not in is followed by a subquery, the filtered result will be There is a NULL value, it is amazing, if you need NULL to exist, convert it
- (3) When not in contains a NULL value, no matter whether it is followed by a constant or a subquery, no result will be returned. This must be noted, especially when it is a subquery, it is necessary to convert NULL or filter NULL according to business requirements value
In short, the general problem is not big when using in, but it is particularly important when using not in, combined with the proper use of this article, the reason for such a
large difference is the judgment of NULL, which is essentially null or is not null , the judgment of in or
not in is equal to (=), so the judgment of NULL is invalid and needs to be kept in mind.