比较MS访问表中的行

时间:2013-02-01 05:07:27

标签: sql ms-access duplicates subquery ms-access-2007

我在这两张表中都有这样的值。我想检查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?是空值吗?如何更改我的选择状态以检查两个值是否为空,它是否相同。

2 个答案:

答案 0 :(得分:1)

您可以在NZ函数周围包含where条件,看看是否有帮助,例如:

NZ(TABLEB.Hrs,0) = NZ(TABLEA.Hrs,0)

答案 1 :(得分:1)

是的,你怀疑Nulls是对的。

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

但是,子查询要求db引擎考虑是否TABLEB.Sft = TABLEA.Shift。而且存在问题...... Null永远不会等于任何东西,甚至不是Null。

查看此即时窗口会话是否澄清了这种情况。

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

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

TrueTABLEB.Sft都为空时,您需要进行比较,返回TABLEA.Shift,当两者都包含相同的非空值时,还需要返回True

(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)
    );