使用 Access 2007,我有一个主数据库和几个从数据库。假设我有一个简单的表格:候选人。
在主数据库中
Id ; Name ; Birthday ; Timestamp
01 ; Henri ; 01-01-1911 ; 01-01-2017
在从数据库中
Id ; Name ; Birthday ; Timestamp
01 ; Henry ; 01-01-1911 ; 01-02-2017
我需要的是,最新的操作记录替换主数据库中的先前记录。在此示例中,从属数据库中的记录将替换主数据库中的记录。
在我当前的解决方案中,我遍历记录集并比较时间戳。它有效,但我想知道是否有更有效和更快的解决方案?也许用SQL?
此致
我将假设 ID 是所有数据库中的唯一标识符,并且从属数据库中没有主数据库中没有的 ID 。否则你会遇到问题,因为 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 query off the union query 来获取每个 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来获取最新的(从)数据,并且你可以加入到主Candidates表并比较时间戳。添加一个 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 允许您这样做。当您在 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 并不完全支持该语法,因此您需要运行如下代码:
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 查询,其语法非常简单:
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
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句