删除重复记录MS Access SQL Microsoft

时间:2015-07-02 21:29:57

标签: sql ms-access

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

请告知如何纠正?

2 个答案:

答案 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;

再次感谢你!