在Access中,我能够运行SELECT查询,找到我需要删除的重复记录,但不能执行将删除它们的查询。
这是查询的代码,它向我显示重复的正确记录并对它们进行分组。它向我显示了1083条记录(它们已分组)
SELECT Count(tblDat01Prod.[MFG #]) AS [CountOfMFG #], Last(tblDat01Prod.[MFG #]) AS [LastOfMFG #], tblDat01Prod.[MFG #]
FROM tblDat01Prod
GROUP BY tblDat01Prod.[MFG #]
HAVING (((Count(tblDat01Prod.[MFG #]))>1));
这是删除记录的代码,它想要删除所有记录,事件虽然我只想删除1083。
DELETE tblDat01Prod.[MFG #]
FROM tblDat01Prod
WHERE (((tblDat01Prod.[MFG #]) In (SELECT Last(tblDat01Prod.[MFG #]) AS LastMFG
FROM tblDat01Prod
GROUP BY [MFG #]
HAVING (((Count(tblDat01Prod.[MFG #]))>1));)));
请告知如何纠正?
答案 0 :(得分:5)
由于多种原因,查询不会按原样运行。主要原因是项目的数量会随着您删除而改变,因此引擎无法跟踪要删除的内容。
话虽如此,您的查询并没有多大意义。 Last函数不应与Count在同一列上。否则,您将删除每个副本,而不仅仅是每个重复的最后一个副本。
如果您有主键,则可以分两步完成。如果您不这样做,则需要额外的步骤,因为您需要一个独特的字段:
如果您没有主键,则备用步骤:添加名为RecordId的自动编号字段。如果您已经有一个主键,则在以下步骤中使用它而不是RecordId。
首先,使用您要删除的ID创建临时表。我们称之为temp_Delete:
SELECT Last([RecordId]) AS LastId INTO temp_Delete
FROM tblDat01Prod
GROUP BY [MFG #]
HAVING Count([MFG #])>1
第二次,运行一个delete语句,该语句使用temp_Delete表来限制您要删除的内容。您将加入RecordId字段(警告:您可能无法在可视化编辑器中执行此操作,因为它会弄乱您的sql。您必须手动编写并运行它。)
DELETE DISTINCTROW tblDat01Prod.*
FROM tblDat01Prod INNER JOIN temp_Delete
ON tblDat01Prod.RecordId = temp_Delete.LastId
安全步骤:如果您一直担心丢失重要数据,我建议在删除前注入另一个步骤。将一个布尔IsDelete列添加到tblDat01Prod并使用temp_Delete表将匹配字段更新为True。然后比较哪些记录设置为删除,哪些记录在删除之前不会被删除。然后删除IsDelete为真的记录而不是上面的步骤2.
最后,删除您的temp_Delete表以及您添加到tblDat01Prod但您不想保留的任何字段。
答案 1 :(得分:1)
非常感谢你的帮助唐!我能够根据我的需要稍微修改你的代码,以确保删除正确的数据,但对你来说,这是一个很棒的帮助+1(如果我有这样做的声誉)。
由于我需要删除输入到数据库中的最旧记录,因此我按照输入日期在工作表视图中对表进行了排序,创建了一个列DeleteOldestEntry,在excel中粘贴了PK并创建了一个增加数字的列表,粘贴了这些数字返回DeleteOldestEntry中的访问权限。然后我修改了你的代码。
SELECT First(tblDat01Prod.[DeleteOldestEntry]) AS OldID, [MFG #] INTO temp_Delete
FROM tblDat01Prod
GROUP BY tblDat01Prod.[MFG #]
HAVING (((Count(tblDat01Prod.[MFG #]))>1));
然后执行删除声明
DELETE DISTINCTROW tblDat01Prod.*
FROM tblDat01Prod INNER JOIN temp_Delete ON tblDat01Prod.DeleteOldestEntry = temp_Delete.OldID;
再次感谢你!