不喜欢和喜欢不返回相反的结果

时间:2016-11-02 09:20:08

标签: sql sql-server tsql sql-like

我有一张包含200条记录的表格,其中10条记录的文字包含“TAX”字样。

我正在执行

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

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

但是当我试图通过

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

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

6 个答案:

答案 0 :(得分:73)

这会返回正确的结果吗?

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

我认为此处NULL值是问题,如果列中包含这些值,则NULL NOT LIKE '%TAX%'将返回UNKNOWN/NULL,因此无法选择。

我建议您阅读handling with NULL valueshere

正如@ughai建议的那样,如果表现有问题,你也可以使用:

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

答案 1 :(得分:18)

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

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

如您所见,数据库可以/不会决定NULL是否大于/等于18。

(B)数据库只返回WHERE子句计算结果为True的行。反转表达式(例如WHERE age >= 18已更改为WHERE age < 18)不会影响未知结果。

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

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

ISNULLCOALESCE等功能可用于将NULL转换为某个值。

答案 2 :(得分:2)

它也发生在我身上!在弄清楚我的头后,我发现这是因为空值,所以你可以使用这个查询来避免它:

WHERE CASE WHEN [TextCol] IS NULL
           THEN 'default' 
           ELSE [TextCol] 
      END NOT LIKE '%TAX%'

答案 3 :(得分:1)

  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
    

答案 4 :(得分:0)

您还需要检查NULL值:

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

这也应该处理空值,这可能是你没有得到输出中所有行的原因。

答案 5 :(得分:0)

在带有int的简单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)