假设
我将假设 ID 是所有数据库中的唯一标识符,并且从数据库中没有 ID 是 not 在主数据库中的。否则你会遇到问题,因为 slave1 可能会将 ID 7 分配给“Fred”,但 slave2 可能会将 ID 7 分配给“Thomas”。
联合查询
SELECT ID, Name, Birthday, Timestamp, 1 AS SlaveNum FROM Candidates_Slave1
UNION ALL
SELECT ID, Name, Birthday, Timestamp, 2 AS SlaveNum FROM Candidates_Slave2
UNION ALL
SELECT ID, Name, Birthday, Timestamp, 3 AS SlaveNum FROM Candidates_Slave3
UNION ALL
...
然后我会从该联合查询中编写一个 group by 查询,以获取每个 ID 及其最大时间戳。
组查询
SELECT ID, max(Timestamp) AS MaxTime FROM UnionQuery
然后将其加入 UnionQuery,并取最小(或最大)SlaveNum(以防多个从属具有相同的最大时间戳)。
加入查询
SELECT GroupQuery.ID, GroupQuery.MaxTime AS Timestamp, min(UnionQuery.SlaveNum) AS SlaveNum
FROM GroupQuery INNER JOIN UnionQuery ON
GroupQuery.ID = UnionQuery.ID AND
GroupQuery.MaxTime = UnionQuery.Timestamp;
现在你可以通过再次内联UnionQuery来获取最新的(从属)数据,并且你可以加入主候选人表并比较时间戳。添加一个 WHERE 子句,检查主表中是否存在小于我们的连接查询的时间戳:
全信息查询
SELECT Candidates_Master.ID,
Candidates_Master.Name AS Name_Master,
Candidates_Master.Birthday AS Birthday_Master,
Candidates_Master.Timestamp AS Timestamp_Master,
UnionQuery.Name AS Name_Slave,
UnionQuery.Birthday AS Birthday_Slave,
UnionQuery.Timestamp AS Timestamp_Slave
FROM (JoinQuery INNER JOIN UnionQuery
ON JoinQuery.ID = UnionQuery.ID AND JoinQuery.SlaveNum = UnionQuery.SlaveNum)
INNER JOIN Candidates_Master ON JoinQuery.ID = Candidates_Master.ID
WHERE Candidates_Master.Timestamp < UnionQuery.Timestamp;
最后,编写更新查询有时会很麻烦,因为严格来说,UPDATE 查询中不应该有 JOIN 子句,但 Access 有时可以让您这样做。 This post 在 Access 中收到“此记录集不可更新”错误时的详细信息。进行更新的 ANSI 方式是这样的:
更新查询
UPDATE Candidates_Master
SET (Name, Birthday, Timestamp) = (SELECT Name_Slave, Birthday_Slave, Timestamp_Slave FROM FullInfoQuery WHERE Candidates_Master.ID = FullInfoQuery.ID)
WHERE EXISTS (SELECT 1 FROM FullInfoQuery WHERE FullInfoQuery.ID = Candidates_Master.ID);
不幸的是,Access 并不完全支持该语法,因此您需要运行以下内容:
UpdateQuery_v2
UPDATE Candidates_Master
SET Name = (SELECT Name_Slave FROM FullInfoQuery WHERE Candidates_Master.ID = FullInfoQuery.ID),
Birthday = (SELECT Birthday_Slave FROM FullInfoQuery WHERE Candidates_Master.ID = FullInfoQuery.ID),
Timestamp = (SELECT Timestamp_Slave FROM FullInfoQuery WHERE Candidates_Master.ID = FullInfoQuery.ID)
WHERE EXISTS (SELECT 1 FROM FullInfoQuery WHERE FullInfoQuery.ID = Candidates_Master.ID);
但是因为它有这么多相关的子查询,所以它可能非常慢/效率低。试试看。一个常见的替代方法(无论如何对我来说)是编写一个 make table 查询将 FullInfoQuery 的结果粘贴到它自己的表中,然后基于该表编写一个 UPDATE 查询,语法非常简单:
UpdateQuery_v3
UPDATE Candidates_Master INNER JOIN tblFullInfoQuery ON Candidates_Master.ID = tblFullInfoQuery.ID
SET Candidates_Master.Name = tblFullInfoQuery.Name_Slave,
Candidates_Master.Birthday = tblFullInfoQuery.Birthday_Slave,
Candidates_Master.Timestamp = tblFullInfoQuery.Timestamp_Slave