我有一张包含200条记录的表格,其中10条记录的文字包含“TAX”字样。
我正在执行
Select * from tbl1 WHERE [TextCol] LIKE '%TAX%'
然后我正确地得到了这10条记录的结果集。
但是当我试图通过
排除这些记录时Select * from tbl1 WHERE [TextCol] NOT LIKE '%TAX%'
它只返回100条记录,而不是190条。
答案 0 :(得分:73)
这会返回正确的结果吗?
Select * from tbl1 WHERE COALESCE([TextCol],'-1') NOT LIKE '%TAX%'
我认为此处NULL
值是问题,如果列中包含这些值,则NULL NOT LIKE '%TAX%'
将返回UNKNOWN/NULL
,因此无法选择。
我建议您阅读handling with NULL
values或here。
正如@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
ISNULL
和COALESCE
等功能可用于将NULL
转换为某个值。
答案 2 :(得分:2)
它也发生在我身上!在弄清楚我的头后,我发现这是因为空值,所以你可以使用这个查询来避免它:
WHERE CASE WHEN [TextCol] IS NULL
THEN 'default'
ELSE [TextCol]
END NOT LIKE '%TAX%'
答案 3 :(得分:1)
Select * from tbl1
WHERE ([TextCol] NOT LIKE '%TAX%') AND ([TextCol] NOT LIKE '%TAX%')
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)