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

Sha*_*nka 58 sql t-sql sql-server sql-like

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

当我执行时

Select * from tbl1 WHERE [TextCol] LIKE '%TAX%'
Run Code Online (Sandbox Code Playgroud)

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

但是,当我试图排除那些记录

Select * from tbl1 WHERE [TextCol] NOT LIKE '%TAX%'
Run Code Online (Sandbox Code Playgroud)

它仅返回100条记录,而不是190条记录.

sag*_*agi 75

这会返回正确的结果吗?

Select * from tbl1 WHERE COALESCE([TextCol],'-1') NOT LIKE '%TAX%'
Run Code Online (Sandbox Code Playgroud)

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

我建议你阅读有关处理NULL值的信息,或者在这里.

正如@ughai建议的那样,如果性能是一个问题,你也可以使用:

  Select * from tbl1 
  WHERE [TextCol] NOT LIKE '%TAX%'
     OR [TextCol] IS NULL
Run Code Online (Sandbox Code Playgroud)

  • 我建议使用`[TextCol] NOT LIKE'%TAX%'或[TextCol] IS NULL`,因为如果用户想要包含"NULL"值,它会有更好的性能 (16认同)
  • "然后`NULL NOT LIKE'%TAX%'`将返回false" - 不,它不会.如果它返回false,那么通过将`NOT`放在更高级别来解决问题是微不足道的:`NOT(NULL LIKE'%TAX%')`如果`NULL LIKE'%TAX%'将返回true `返回false.相反,它返回未知.未知也表示不会选择该行. (4认同)
  • 他说"190条记录",所以我怀疑性能是一个问题,但无论如何编辑,因为其他人可能会读到这个答案@ughai. (3认同)
  • 它不是"如果性能是一个问题",那也是明显更清晰的代码版本.拯救令人费解的"-1"来自哪里. (3认同)

Sal*_*n A 18

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

21   >= 18 -- True
15   >= 18 -- False
NULL >= 18 -- Unknown
Run Code Online (Sandbox Code Playgroud)

如您所见,数据库可以/不会决定是否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
Run Code Online (Sandbox Code Playgroud)

诸如ISNULL和之类的函数COALESCE可用于转换NULL为某些值.

  • 更正:涉及"NULL"值的所有操作都会导致**`UNKNOWN`**...除非它们不是例如`SELECT COUNT(TextCol)AS tally FROM tbl1` (4认同)