4

我在 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

4 回答 4

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

我要做的是系统地删除除前两个之外的所有连接条件,直到您发现记录丢失。然后你就会知道你的问题在哪里。

于 2012-04-24T17:49:51.650 回答
3

这不应该发生。除非同时插入/删除行,

查询:

SELECT *
FROM a LEFT JOIN b
         ON whatever ;

永远不应返回少于以下的行数:

SELECT *
FROM a ;

如果发生这种情况,那就是一个错误。您确定查询完全像这样(并且您没有省略一些细节,例如WHERE子句)?您确定第一个返回 4149 行,第二个返回 4103 行吗?*您可以通过将上述更改为 来进行另一次检查COUNT(*)

于 2012-04-24T17:55:03.627 回答
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)
        );
于 2012-04-24T17:39:06.550 回答
0

不管它值多少钱,因为这似乎是一个欺骗性的错误,任何额外的信息都可以帮助解决它,我也遇到了同样的问题。

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

我正在逐渐完善和更改我的查询。它有一个派生表(D)。整个事情被制作成一个派生表(T),然后连接到最后一个表(L)。无论如何,在其发展的某一时刻,T 中没有一个源自 D 的字段参与到 L 的连接。然后问题就出现了,总行数神秘地变得少于主表,这应该是不可能的. 一旦我再次让 D 中的一个字段(通过 T)参与到 L 的连接中,该数字再次增加到正常。

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

于 2014-05-05T21:53:54.920 回答