为什么我的左连接在Access中的行数少于左表?

时间:2012-04-24 17:09:46

标签: sql database ms-access

我在MS Access 2010数据库中有两个表:TBLIndividuals和TblIndividualsUpdates。它们具有大量相同的数据,但两个表中给定人员的记录的主键可能不同。所以我在名称和生日的两个表之间进行连接,以查看哪些记录对应。我正在使用左连接,这样我也可以为TblIndividualsUpdates但不在TBLIndividuals中的人获取行。这样我知道哪些记录需要添加到TBLIndividuals以使其更新。

SELECT TblIndividuals.PersonID AS OldID, 
TblIndividualsUpdates.PersonID AS UpdateID
FROM TblIndividualsUpdates LEFT JOIN TblIndividuals 
ON ( (TblIndividuals.FirstName = TblIndividualsUpdates.FirstName) 
and (TblIndividuals.LastName = TblIndividualsUpdates.LastName) 
AND (TblIndividuals.DateBorn = TblIndividualsUpdates.DateBorn 
    or (TblIndividuals.DateBorn is null 
        and (TblIndividuals.MidName is null and TblIndividualsUpdates.MidName is null 
            or TblIndividuals.MidName = TblIndividualsUpdates.MidName))));

TblIndividualsUpdates有4149行,但查询只返回4103行。 TblIndividualsUpdates中有大约50条新记录,但查询结果中只有4行,其中OldID为空。

如果我将数据从Access导出到PostgreSQL并在那里运行相同的查询,我将获得所有4149行。

这是Access中的错误吗? Access的左连接语义和PostgreSQL之间有区别吗?我的数据库是否已损坏(压缩和修复没有帮助)?

4 个答案:

答案 0 :(得分:4)

ON ( 

        TblIndividuals.FirstName = TblIndividualsUpdates.FirstName

        and 

        TblIndividuals.LastName = TblIndividualsUpdates.LastName

        AND (
                 TblIndividuals.DateBorn = TblIndividualsUpdates.DateBorn      
                 or 
                 (
                     TblIndividuals.DateBorn is null          
                     and 
                     (
                     TblIndividuals.MidName is null 
                     and TblIndividualsUpdates.MidName is null              
                     or TblIndividuals.MidName = TblIndividualsUpdates.MidName
                     )
                 )
             )
    );

我会做的是系统地删除除前两个之外的所有连接条件,直到找到记录为止。然后你会知道你的问题所在。

答案 1 :(得分:3)

这绝不会发生。除非在此期间插入/删除行,否则

查询:

SELECT *
FROM a LEFT JOIN b
         ON whatever ;

永远不会返回比以下更少的行:

SELECT *
FROM a ;

如果它发生了,那就是一个错误。你确定查询完全是这样的(你没有省略一些细节,比如WHERE子句)?你确定第一行返回4149行,第二行返回4103行吗?您可以通过将上面的*更改为COUNT(*)来进行其他检查。

答案 2 :(得分:1)

从两个表中删除包含那些JOIN字段(FirstName,LastName和DateBorn)的索引。然后看看你是否得到了预期 这个简化的查询有4,149行。

SELECT
    i.PersonID AS OldID, 
    u.PersonID AS UpdateID
FROM
    TblIndividualsUpdates AS u
    LEFT JOIN TblIndividuals AS i
    ON
        (
            (i.FirstName = u.FirstName) 
        AND (i.LastName = u.LastName) 
        AND (i.DateBorn = u.DateBorn)
        );

答案 3 :(得分:0)

无论它值多少,因为这似乎是一个欺骗性的错误,任何其他信息可以帮助解决它,我遇到了同样的问题。

查询太大了,无法在此发布,我现在没有时间将其减少到合适的位置,但我可以报告我发现的内容。在下面,所有连接都是左连接。

我正在逐步完善和改变我的查询。它有一个派生表(D)。整个事情被制作成派生表(T),然后加入到最后一个表(L)。在任何情况下,在其发展的一个点上,起源于D的T中的任何一个字段都没有参与到L的连接。然后问题发生了,总行数神秘地变得比主表少,这应该是不可能的。一旦我再次让D中的一个区域(通过T)参与到L中,该数字再次升至正常。

当D中的连接条件没有被参与(通过T)连接到L时,就好像D的连接条件被移动到WHERE子句。但我真的不知道解释是什么。< / p>