Teradata 处理零不平等最实际的方法是什么?

Teradata 处理零不平等最实际的方法是什么?,teradata,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

我不理解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为null,y为null这应该返回false,因为只有x为null

x=y这应该返回false,因为两者不相等

但是,当我将not放在整个表达式前面时,它返回false。当你说不假的时候,你应该是真的。我能想到的唯一解决方案是使用ZEROIFNULL或Teradata的其他与null相关的函数之一,但这似乎更像是一种让null不等式起作用的黑客

我怎样才能让null不等式以它看起来应该的方式工作呢

更新:谢谢你的回答,德诺思。空值是很棘手的,你对未知值的解释让我想到了

现在我更了解了,下面是我完全修改过的SQL。我试图做的是确定是否将记录移动到审核表。我只想在其AuditOverride标志为1或至少一个字段已更改时审核记录。向包含多个表达式的条件中抛出未知值将导致整个表达式返回未知值。因为将not放在unknown前面也会导致unknown,所以我使用case语句将其转换为0,就像zeroifnull一样

德诺思,如果你能找到更好的方法来处理这样的不平等比较,我完全赞成你的想法

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和非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

这确实有助于我理解讨厌的空值。我也曾在Oracle中尝试过这种方法,您是对的,它的行为方式也是一样的。然而,Oracle和Teradata并不总是对空值一视同仁。如果在Oracle中从dual运行select'a'| | | null | | | | z',则会得到az。但是,如果在Teradata中运行select'a'| | null | | |'z',则会得到null。这是Oracle中的一个已知功能,空字符串和null之间没有区别。在您的情况下,Oracle将其视为一个,但没有一致的规则,例如,在“替换”中,它是,而在“转换”中,它是空的:-