【问题标题】:NOT LIKE and LIKE not returning opposite resultNOT LIKE 和 LIKE 不返回相反的结果
【发布时间】:2017-03-15 13:08:54
【问题描述】:

我有一个包含 200 条记录的表,其中 10 条记录的文本包含“TAX”一词。

当我执行时

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

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

但是当我试图排除这些记录时

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

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

【问题讨论】:

  • 该列是否有 null 值?
  • 是的,该列中有空值
  • 尽可能避免在搜索字符串的开头使用%。它很重。
  • @MoslemBenDhaou 有一些方法可以优化中缀查询。我相信 SQL Server 中的主要方法是全文搜索机制,但我可能不知道更好的选择。在 PostgreSQL 中,您可以使用三元组索引来提高它们的效率。但是,对于 200 行的表,它可能甚至不值得索引。
  • 什么? MySQL 是否符合“青少年词汇”标准?

标签: sql sql-server tsql sql-like


【解决方案1】:

这会返回正确的结果吗?

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

【讨论】:

  • 我建议使用[TextCol] NOT LIKE '%TAX%' OR [TextCol] IS NULL,因为如果用户想要包含NULL 值,它会有更好的性能
  • 他说“190 条记录”,所以我怀疑性能是个问题,但还是编辑了,因为其他人可能会读到这个答案@ughai。
  • 谢谢! NULL 是问题所在。
  • "然后NULL NOT LIKE '%TAX%' 将返回 false" -- 不,它不会。如果它返回 false,那么通过将 NOT 置于更高级别来解决问题将是微不足道的:如果 NULL LIKE '%TAX%' 返回 false,NOT(NULL LIKE '%TAX%') 将返回 true。相反,它返回未知。未知也意味着不会选择该行。
  • 这不是“如果性能是一个问题”,这也是代码的明显更清晰的版本。让人们不解“-1”从何而来。
【解决方案2】:

(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 转换为某个值。

【讨论】:

  • 更正:所有涉及 NULL 值的操作都会导致 UNKNOWN ...除非它们没有,例如SELECT COUNT(TextCol) AS tally FROM tbl1
  • 您的编辑“所有操作”->“比较运算符”很好 +1
【解决方案3】:
  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
    

【讨论】:

  • WHERE ([TextCol] NOT LIKE '%TAX%') AND ([TextCol] NOT LIKE '%TAX%') 有什么意义?
  • 虽然这段代码 sn-p 可以解决问题,包括解释 really helps 以提高您的帖子质量。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人!请edit您的答案添加解释,并说明适用的限制和假设。
【解决方案4】:

我在带有空值的简单 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) 

【讨论】:

    猜你喜欢
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多