将任何内容与 NULL 进行比较会导致 UNKNOWN 而不是 FALSE。
这实际上与返回 false 具有相同的效果,因为查询将仅返回数量不为空且大于 0 的行,但您应注意不要假设数量为空时比较的结果为假
例如,这也将无法返回空行:
WHERE NOT(amount > 0)
amount > 0
是 UNKNOWN 不是 FALSE。如果它是假的,那么 NOT 会变成真的
您可以认为 NULL 是一种污染物,它会在它所接触的每个布尔条件和操作中一直上升,将它们全部变为未知,然后在最后一刻“变为假”,因为布尔谓词的最终评估者需要一个真的
总的来说,您可以将 UNKNOWN 视为 NULL 的同义词;UNKNOWN 相对局限于布尔逻辑。在其他上下文中,例如涉及 NULL 的数学运算会导致 null (0+NULL = NULL)。唯一可以对 null 起作用并产生布尔值的操作是amount IS [NOT] NULL
根据您的代码审查,如果他们坚持“必须合并任何可能为空的值”,那么业务规则似乎是系统不能容忍空值——在这种情况下,应该是列不为空,仅填充实际值。通过可能会或可能不会更改它的函数传递任何值会削弱索引的使用并给查询计划带来问题。人们可能希望智能优化器可以在简化之前扩展/重写ISNULL(amount, 0) > 0
以amount > 0 or (amount is null and 0>0)
完全删除括号中的条件,但这并不一定总是那么简单。最好不要一开始就胡说八道,而不是耸耸肩然后说“好吧,在我的简单测试用例中,它似乎并没有让事情变慢”
没有任何考虑或理由而应用一揽子规则可能会导致系统性能非常差。你将如何将此反馈给制定规则的人可能很难处理办公室政治,因为他们的方法是错误的,但他们不太可能承认或希望被告知
顺便说一句,您可能会觉得等效查询更好地捕捉了您正在尝试做的事情的概念:
SELECT m.Name
FROM Members m
WHERE NOT EXISTS(
SELECT 1
FROM Fees f
WHERE m.Id = F.memberId and F.AmountDue > 0
)
左反连接模式是我最喜欢的各种模式,但我觉得这更不言自明 - “所有成员都没有相关的欠款记录”。NOT IN 也使这变得非常易读,但应谨慎使用,因为某些数据库实现可能非常幼稚:
SELECT m.Name
FROM Members m
WHERE NOT IN (
SELECT F.MemberId
FROM Fees f
WHERE F.AmountDue > 0
)
SQL Server 很可能会重写 LEFT JOIN WHERE NULL/WHERE NOT EXISTS/WHERE NOT IN,因此它们的计划和执行方式相同,但您可能会发现在接下来的 IN 方法的这个/dim view 中没有太多欣赏代码审查:)