null LIKE '%text%'?

null LIKE '%text%'?

尽管该字段包含 NULL 值,但由于条件 not like '%TEST%' 我丢失了很多记录。

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%'

Table credit_case 包含完整数据,而 table 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 的记录没有丢失。 为什么会这样?

在第一种情况下,有一个条件子句将从结果中过滤掉一些记录。

在第二种情况下,master table 上没有条件子句。你所做的实际上是

select * 
from credit_case cc
left join [SUBTABLE] 

这样绝对可以给你一份完整的大师名单table,credit_case

在第一种情况下,left join 返回所有行,然后 where 子句由于 Nulls 而过滤掉行

在第二种情况下,where 子句由于空值而过滤掉了行。然后左连接将它们添加回去。 如果你运行 EXPLAIN PLAN,你可以看到操作的顺序,是先发生空过滤还是左连接包含

  • null 永远不会等于另一个值,包括 null
  • null 永远不会不等于另一个值,包括 null.
  • null 永远不像其他值,包括 null
  • null 永远不会不同于其他值,包括 null.

null 进行比较的唯一方法是使用 is nullis not null。 None 这些查询将永远 return 一行。

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 nullis not null 子句

where (   cl.name_full not like '%TEST%'
       or cl.name_full is null)

将 return 具有 null 值的行 name_full

当您评估 NULL AND 或 OR 条件时,结果始终为假。

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%' 的记录都会显示。并且 NULL 未在此处使用“%TEST%”进行评估。