1

我在这两个表中有这样的值。我想检查 TableA 和 TableB 中的重复项

    TABLEA
    StaffName   Shift   Hrs
    ABC           1      12
    DEF                  23
    XYZ           2          


    TABLEB
    StaffN       Sft   Hrs
    ABC           1      12
    DEF                  23
    XYZ           2          

但是,当我做一个

  SELECT * FROM TABLEA 
  WHERE NOT EXISTS 
  (SELECT * FROM TABLEB.StaffN = TABLEA.StaffName AND
  TABLEB.Sft = TABLEA.Shift AND
  TABLEB.Hrs = TABLEA.Hrs); 

为什么我会返回 DEF 和 XYZ?是因为空值吗?以及如何更改我的选择语句以检查两个值是否为空,是否相同。

4

2 回答 2

1

您可以将您的 where 标准包装在NZ函数周围,看看是否有帮助,例如:

NZ(TABLEB.Hrs,0) = NZ(TABLEA.Hrs,0)
于 2013-02-01T05:49:24.453 回答
1

是的,你怀疑 Null 是对的。

考虑“DEF”行中的 3 个值:DEF;空值; 23. 人们可能会说这些行是重复的,因为两个表中的所有 3 个值都相同。

但是,子查询要求数据库引擎考虑是否TABLEB.Sft = TABLEA.Shift. 还有一个问题……一个 Null 永远不可能等于任何东西,甚至另一个 Null 也不可能。

看看这个立即窗口会话是否澄清了情况。

? 1 = 1
True
? 1 = 2
False
? 1 = Null
Null
? Null = Null
Null

因此,当两个字段都为 Null 时,比较TABLEB.Sft = TABLEA.Shift被评估为 Null。db 引擎将仅包含比较为 的行True,因此排除了那些“DEF”行。同样的逻辑解释了为什么“XYZ”行被排除在外。

您需要一个比较,它True在两者都为 Null 时返回,并且TABLEB.Sft在两者都包含相同的非 Null 值时返回。 TABLEA.ShiftTrue

(TABLEB.Sft Is Null AND TABLEA.Shift Is Null)
OR
(TABLEB.Sft = TABLEA.Shift)

试试这个查询:

SELECT *
FROM
    TABLEA AS a
    INNER JOIN TABLEB AS b
    ON a.StaffName = b.StaffN
WHERE
    (
        (a.Shift Is Null AND b.Sft Is Null)
        OR
        (a.Shift = b.Sft)
    )
    AND
    (
        (a.Hrs Is Null AND b.Hrs Is Null)
        OR
        (a.Hrs = b.Hrs)
    );
于 2013-02-01T05:50:12.487 回答