我不了解Teradata对无效不平等比较的实现。您可以在SQLA中运行此SQL:
select
null x, current_date y,
case
when
not
--ZEROIFNULL(x) = ZEROIFNULL(y)
((x is null and y is null) or x = y)
then 1
else 0
end z
您会注意到z
返回0,但我觉得应该返回1.这是我的理由:
x is null and y is null
这应该返回false,因为只有x
为空。
x = y
这应该返回false,因为两者不相等。
但是,当我将not
放在整个表达式的前面时,它返回false。当你说not false
时,你应该成真。我能想到的唯一解决方案是使用ZEROIFNULL
或Teradata的其他一些与空相关的函数,但这看起来更像是一个让零不等式起作用的黑客。
如何让null不等式以它看起来应该的方式工作?
更新:感谢您的回答,dnoeth。空洞是棘手的,你对unknown
的解释会引导我this very informative Wiki article。
现在我明白了,这是我完全修改过的SQL。我要做的是确定是否将记录移动到审计表。我只想审核一条记录,如果1)其AuditOverride
标志= 1或者至少有一个字段已经改变。将unknown
投入包含多个表达式的条件将导致整个表达式返回unknown
。因为将not
放在unknown
之前也会产生unknown
,所以我使用case
语句将其转换为0(如zeroifnull
)。
dnoeth,如果你看到一个更好的方法来处理这样的不平等比较,我就是为了听你的想法。
select
1 Table1Field1, 1 Table1Field2,
1 Table2Field1, 1 Table2Field2,
0 AuditOverride,
case
when
AuditOverride = 1 or
case
when
(
(Table1Field1 is null and Table1Field2 is null) or
Table1Field1 = Table1Field2
) and
(
(Table2Field1 is null and Table2Field2 is null) or
Table2Field1 = Table2Field2
) and
1=1
then 0 --no differences in values; do not audit
else 1 --at least 1 change has occurred; move to audit table
end = 1
then 1
else 0
end MoveToAuditTable
答案 0 :(得分:2)
这不仅是一个与Teradata相关的问题,这是每个RDBMS应该返回相同的三向逻辑: - )
基于SQL的三值逻辑和De Morgan定律:
不(A或B)与(不是A)和(不是B)相同。
任何与NULL的比较都会返回UNKNOWN,它与FALSE不同,NOT UNKNOWN会再次导致UNKNOWN。
所以你的情况是没有错,而且没有未知 = 真实和未知 = 未知
您必须将其更改为:
select
null x, current_date y,
case
when
((x is null and y is null) or x = y)
then 0
else 1
end z