处理零不等式的最实用方法是什么?

时间:2014-04-08 21:26:54

标签: teradata

我不了解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

1 个答案:

答案 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