NOT LIKE 和 LIKE 不返回相反的结果

NOT LIKE and LIKE not returning opposite result

我有一个包含 200 条记录的 table,其中 10 条记录的文本包含单词 'TAX'。

当我执行时

Select * from tbl1 WHERE [TextCol] LIKE '%TAX%'

然后我正确地得到了包含这 10 条记录的结果集。

但是当我试图通过

排除这些记录时
Select * from tbl1 WHERE [TextCol] NOT LIKE '%TAX%'

它只返回 100 条记录,而不是 190。

  1. Select * from tbl1 
    WHERE ([TextCol] NOT LIKE '%TAX%') AND ([TextCol] NOT LIKE '%TAX%')
    
  2. select * from tbl1
    where [TextCol] NOT LIKE '%TAX%' OR [TextCol] IS NULL
    

这个 return 是正确的结果吗?

Select * from tbl1 WHERE COALESCE([TextCol],'-1') NOT LIKE '%TAX%'

我认为 NULL 值是这里的问题,如果该列包含它们,那么 NULL NOT LIKE '%TAX%' 将 return UNKNOWN/NULL 因此不会被选中。

我建议你阅读有关 handling with NULL values , or here 的内容。

正如@ughai 所建议的,如果性能是一个问题,您还可以使用:

  Select * from tbl1 
  WHERE [TextCol] NOT LIKE '%TAX%'
     OR [TextCol] IS NULL

(A) SQL 比较运算符会产生三个可能的值:True、False 和 Unknown。如果一个或两个操作数是 NULL,那么结果是未知的。考虑以下示例,我们将一些值(一个人的年龄)与常量 (18) 进行比较:

21   >= 18 -- True
15   >= 18 -- False
NULL >= 18 -- Unknown

如您所见,数据库 can/will 无法确定 NULL 是否大于 than/equal 到 18。

(B) 数据库将仅 return 行,其中 WHERE 子句的计算结果为 True。反转表达式(例如 WHERE age >= 18 更改为 WHERE age < 18)不会影响未知结果。

您可以使用 IS [NOT] NULL 来匹配 NULL 值。以下查询将 select 列与模式不匹配或列为 NULL 的行:

WHERE [TextCol] NOT LIKE '%TAX%' OR [TextCol] IS NULL

ISNULLCOALESCE 等函数可用于将 NULL 转换为某个值。

我在具有空值的简单 int 列上使用 IN 运算符时遇到了同样的问题。 我发现这些并不像我想的那样彼此相反。 (我可以通过行数判断)

select * from Dest where id in(select id from Source)
select * from Dest where id NOT in(select id from Source)

为了让彼此反转,我也不得不这样重写它们:

select * from Dest where isnull(id,-2)  in(select isnull(id,-1) from Source) 
select * from Dest where isnull(id,-2) NOT in(select isnull(id,-1) from Source)