我在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之间有区别吗?我的数据库是否已损坏(压缩和修复没有帮助)?
答案 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>