由于条件not like '%TEST%'
虽然该字段包含NULL
值,但我缺少许多记录。
select *
from credit_case cc
left join (select skp_case, name_full from client) cl on cc.skp_case = cl.skp_case
where cl.name_full not like '%TEST%'
表credit_case
包含完整数据,而表client
则不包含。
当我重写它时
select *
from credit_case cc
left join (select skp_case, name_full from client
where name_full not like '%TEST%') cl on cc.skp_case = cl.skp_case
来自credit_case
的记录不会丢失。为什么?
null
永远不会等于另一个值,包括null
。null
永远不会与另一个价值不相等,包括null
。null
永远不会像其他价值,包括null
。null
永远不会与另一个价值不同,包括null
。与null
进行比较的唯一方法是使用is null
或is not null
。这些查询都不会返回任何行。
select *
from table
where column = null;
select *
from table
where column != null;
select *
from table
where column like null;
select *
from table
where column not like null;
您需要明确包含is null
或is not null
子句
where ( cl.name_full not like '%TEST%'
or cl.name_full is null)
将为null
返回name_full
值的行。
在第一种情况下,有一个条件子句将从结果中过滤掉一些记录。
在第二种情况下,主表上没有条件子句。你在做什么呢
select *
from credit_case cc
left join [SUBTABLE]
所以这肯定会给你一个完整的主表列表,credit_case
当您评估NULL AND或OR Condition时,结果始终为false。
select *
from credit_case cc
left join (select skp_case, name_full from client) cl on cc.skp_case = cl.skp_case
where cl.name_full not like '%TEST%'
对于在credit_case中不存在记录的情况,此处将客户端结果保留为cl.name_full作为NULLS。
试试这个,你会明白:
select cl.name_full
from credit_case cc
left join (select skp_case, name_full from client) cl on cc.skp_case = cl.skp_case
所有NULL记录都是从查询结果中省略的记录。
另一方面,对于第二种情况,当你重写时
select *
from credit_case cc
left join (select skp_case, name_full from client
where name_full not like '%TEST%') cl on cc.skp_case = cl.skp_case
假设name_full不为NULL,则显示name_full中没有'%TEST%'的所有记录。此处不使用'%TEST%'评估NULL。
在第一种情况下,左连接返回所有行,然后where子句由于Null而过滤掉行
在第二种情况下,where子句由于空值而过滤掉行。然后左连接将它们重新添加。如果运行EXPLAIN PLAN,您可以看到操作的顺序,是否首先发生由于null引起的过滤,或者是否发生了由于左连接引起的包含