我不明白 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
为 null。
x = y
这应该返回 false,因为两者不相等。
但是,当我将 not
放在整个表达式前面时,它会返回 false。当你说not false
时,你应该得到true。我能想到的唯一解决方案是使用 ZEROIFNULL
或 Teradata 的其他与 null 相关的函数之一,但这似乎更像是一种让 null 不等式发挥作用的 hack。
我怎样才能让零不平等以它看起来应该的方式工作?
更新:感谢您的回答,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
最佳答案
这不仅是与 Teradata 相关的问题,这是每个 RDBMS 都应该返回相同的三向逻辑:-)
基于SQL的三值逻辑和德摩根定律:
非(A 或 B) 与(非 A)AND(非 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
关于teradata - 处理零不等式最实用的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22948526/