我尝试删除数据库中的重复记录。唯一的区别是PrimaryKey是一个uniqueidentifier。我有大约1500个被欺骗的条目,所以我正在查看大约3000个条目。所以我分开了大约60个条目(根据收到的日期)并执行了我的代码,将它们减少到30,而OH CRAP 30则消失了!这是我试过的代码:
DELETE dupes
FROM [emailTable] dupes, [emailTable] fullTable
WHERE (dupes.ReceivedOn > '2009-08-18 23:59:59.999' AND dupes.ReceivedOn < '2009-08-20 00:00:00.000')
AND (dupes.emlPath = fullTable.emlPath)
AND NOT (dupes.GUID = fullTable.GUID)
我的目标是删除副本。我不关心哪一个......但是我需要两个条目中的一个留在服务器上...任何人都可以解释我做错了什么?
答案 0 :(得分:7)
您可以在没有第二张表的情况下执行此操作。像这样:
SELECT * FROM emailTable
WHERE EXISTS (
SELECT * FROM emailTable AS t2
WHERE t2.emlPath = emailTable.emlPath AND
t2.GUID > emailTable.GUID)
这将显示哪些记录即将被删除。如果没关系,请将其更改为:
DELETE FROM emailTable
WHERE EXISTS (
SELECT * FROM emailTable AS t2
WHERE t2.emlPath = emailTable.emlPath AND
t2.GUID > emailTable.GUID)
t2.GUID > emailTable.GUID
将确保包含该emlPath
的一条记录保留在表格中。
答案 1 :(得分:2)
您应该使用子选择进行删除,而不是连接。
以这种方式执行此操作的好处是,您可以在实际删除之前预览要删除的GUID。 (只需自己运行select查询)
这个outta这样做,它将删除最小的GUID
delete from emailTable where GUID in
(
select MIN(dupe.GIUD) from emailTable dupe
INNER JOIN emailTable noDupe
ON dupe.emlPath=noDupe.emlPath
where recievedOn between '2009-8-18' and '2009-8-20'
GROUP BY dupe.emlPath
)
答案 2 :(得分:1)
您做错了是您的查询不排除任何重复项。它挑选出与具有相同路径的另一个副本不同的重复项,但每个重复项与另一个重复项不同。
您要做的是首先挑选出您想要保留的副本,例如:
select min(GUID)
from emailTable
where ReceivedOn > '...' and ReceivedOn < '...'
group by emlPath
having count(*) > 1
然后删除除那些之外的所有重复项。
答案 3 :(得分:0)
您不应在加入中使用“=”。即“AND NOT(dupes.GUID = fullTable.GUID)”由于重复行的GUID必须不同,此条件不会执行任何操作。
你应该使用大于。即
delete from emailTable
WHERE EXISTS
(
SELECT ID FROM emailTable t2
WHERE emailTable.GUID > t2.GUID
AND emailTable.emlPath= t2.emlPath
)
答案 4 :(得分:0)
我更喜欢使用公用表表达式和ROW_NUMBER():
with cte as (
select row_number() over (partition by emlPath order by GUID) as eml_no
, ReceivedOn
from [emailTables])
delete from cte
where eml_no > 1
and ReceivedOn between '2009-08-18 23:59:59.999' AND '2009-08-20 00:00:00.000';
我喜欢这个,因为它可以控制删除哪个重复行。我可以删除第三个并保留两个,我可以选择我想要保留第一个的任何订单号,它可以很好地处理关系。
答案 5 :(得分:0)
由于所有帖子的帮助,这是我最终得到的代码:
DELETE A
FROM [emailTable] A, [emailTable] B
WHERE A.MessageID = B.MessageID
AND A.GUID > B.GUID