SQL 和 where 子句中的 NULL 值
所以我有一个简单的查询,返回产品列表
SELECT Model, CategoryID
FROM Products
WHERE (Model = '010-00749-01')
这返回
010-00749-01 00000000-0000-0000-0000-000000000000
010-00749-01 NULL
这是正确的,所以我只想要类别ID不是'00000000-0000-0000-0000-000000000000'的产品,所以我有
SELECT Model, CategoryID
FROM Products
WHERE (Model = '010-00749-01')
AND (CategoryID <> '00000000-0000-0000-0000-000000000000')
但是这不返回结果。所以我将查询更改为
SELECT Model, CategoryID
FROM Products
WHERE (Model = '010-00749-01')
AND ((CategoryID <> '00000000-0000-0000-0000-000000000000') OR (CategoryID IS NULL))
Which returns预期结果
010-00749-01 NULL
有人可以向我解释这种行为吗? 微软 SQL Server 2008
So I have a simple query that returns a listing of products
SELECT Model, CategoryID
FROM Products
WHERE (Model = '010-00749-01')
This returns
010-00749-01 00000000-0000-0000-0000-000000000000
010-00749-01 NULL
Which is correct, so I wanted only the products whose CategoryID is not '00000000-0000-0000-0000-000000000000' so I have
SELECT Model, CategoryID
FROM Products
WHERE (Model = '010-00749-01')
AND (CategoryID <> '00000000-0000-0000-0000-000000000000')
But this returns no result. So I changed the query to
SELECT Model, CategoryID
FROM Products
WHERE (Model = '010-00749-01')
AND ((CategoryID <> '00000000-0000-0000-0000-000000000000') OR (CategoryID IS NULL))
Which returns expected result
010-00749-01 NULL
Can someone explain this behavior to me?
MS SQL Server 2008
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
查看联机丛书上的完整参考资料- 默认情况下 ANSI_NULLS 处于开启状态,这意味着您需要使用您已经完成的方法。否则,您可以在查询开始时关闭该设置以切换行为。
下面是一个简单的示例,演示了与 NULL 比较的行为:
Check out the full reference on Books Online - by default ANSI_NULLS is on meaning you'd need to use the approach you have done. Otherwise, you could switch that setting OFF at the start of the query to switch the behaviour round.
Here's a simple example to demonstrate the behaviour with regard to comparisons against NULL:
一般来说,您必须记住 NULL 通常意味着 UNKNOWN。这意味着如果您说
CategoryID <> '00000000-0000-0000-0000-000000000000'
您必须假设查询只会返回它知道符合您的条件的值。由于存在 NULL(未知)结果,因此它实际上不知道该记录是否符合您的条件,因此不会在数据集中返回。In general, you have to remember that NULL generally means UNKNOWN. That means if you say
CategoryID <> '00000000-0000-0000-0000-000000000000'
you have to assume that the query will only return values that it KNOWS will meet your criteria. Since there is a NULL (UNKNOWN) result, it does not actually know if that record meets your criteria and therefore will not be returned in the dataset.基本上,NULL 是不存在任何值。因此,尝试将 CategoryId 中的 NULL 与查询中的 varchar 值进行比较将始终导致错误的评估。
您可能想尝试使用 COALESCE 函数,例如:
EDIT
正如
AdaTheDev
所指出的,COALESCE 函数将否定 CategoryID 列上可能存在的任何索引,这可能会影响查询计划和性能。Basically, a NULL is the absence of any value. So trying to compare the NULL in CategoryId to a varchar value in the query will always result in a false evaluation.
You might want to try using the COALESCE function, something like:
EDIT
As noted by
AdaTheDev
the COALESCE function will negate any indices that may exist on the CategoryID column, which can affect the query plan and performance.看看这个:
look at this:
Null 得到特殊对待。您需要显式测试 null。请参阅 http://msdn.microsoft.com/en-us/library/ms188795。 ASPX
Null gets special treatment. You need to explicitly test for null. See http://msdn.microsoft.com/en-us/library/ms188795.aspx
您可以尝试使用
Coalesce
函数为具有null
的字段设置默认值:我认为问题在于您对
NULL
的理解基本上意味着“什么都没有”。你不能将任何东西与任何东西进行比较,就像你不能将一个数字除以 0 一样。这只是数学/科学的规则。编辑:
正如 Ada 所指出的,这可能会导致索引字段不再使用索引。
解决方案:
create index ... coalesce(field)
not null
约束来防止NULL 我的事实上的标准是始终分配默认值并且绝不允许空值You may try using the
Coalesce
function to set a default value for fields that havenull
:I think the problem lies in your understanding of
NULL
which basically means "nothing." You can't compare anything to nothing, much like you can't divide a number by 0. It's just rules of math/science.Edit:
As Ada has pointed out, this could cause an indexed field to no longer use an index.
Solution:
create index ... coalesce(field)
not null
constraint to prevent NULLs from ever appearing