如何从SQL表中删除所有重复记录?

6

你好,我有一个名为FriendsData的表,其中包含如下所示的重复记录。

fID UserID  FriendsID       IsSpecial      CreatedBy
-----------------------------------------------------------------
1   10         11            FALSE            1
2   11          5            FALSE            1
3   10         11            FALSE            1
4    5         25            FALSE            1 
5   10         11            FALSE            1
6   12         11            FALSE            1
7   11          5            FALSE            1
8   10         11            FALSE            1
9   12         11            FALSE            1

我想使用MS SQL删除重复的组合行?从MS SQL FriendsData表中删除最新的重复记录。这里我附上了一个突出显示重复列组合的图像。 如何从SQL表中删除所有重复的组合?
5个回答

13

试试这个

DELETE
FROM FriendsData 
WHERE fID NOT IN
(
SELECT MIN(fID)
FROM FriendsData 
GROUP BY UserID, FriendsID)

看看这里

或者这里有更多可以做你想做的事情的方法。

希望这能帮到你。


1
@Abhishek:这将保留最近的重复项,而不是你在问题中所说的“删除最新的重复项”。 - OMG Ponies
好的,@OMG,我明白你的意思了。如果我在上面的查询中将Max()替换为Min(),那么它会从SQL表中删除最新的重复记录。我是对的吗? - Abhishek B.
你好 @arsenmkrt,我在你的查询中将Max()替换为Min(),这样就可以删除所有最新的重复记录了。我说得对吗? - Abhishek B.
也可以尝试使用join :),你可以尝试我的回答,无论你是否已经标记了这个答案 :) 它可能会更快!! - Pankaj
1
我知道这很老,但是为了记录,你需要更改SQL以在mysql中工作,因为出现错误1093(错误代码:1093。您无法在FROM子句中指定目标表“xxx”进行更新)最终的SQL应该像这样: DELETE FROM FriendsData WHERE fID NOT IN ( SELECT fID from ( SELECT MIN(fID) AS fID FROM FriendsData GROUP BY UserID, FriendsID ) as something ) - Ruan Carlos

3

这似乎与直觉相反,但您可以从公共表达式中删除数据(在特定情况下)。因此,我会这样操作:

with cte as (
  select *, 
     row_number() over (partition by userid, friendsid order by fid) as [rn]
  from FriendsData
)
delete cte where [rn] <> 1

这将保留fid最低的记录。如果您需要其他内容,请在over子句中更改排序方式。

如果可以的话,对表格设置唯一性约束条件,这样就不必再进行此操作了。如果仍然存在漏洞,那么船只即使抽水也没有用!


1
感谢您的回复。关键字中缺少查询语句。以下是代码: “with cte as ( select *, row_number() over (partition by userid, friendsid order by fid) as [rn] FROM FriendsData ) delete cte where [rn] <> 1 ” 我的理解是否正确? - Abhishek B.
啊,是的...我在CTE中漏掉了FROM子句。对此很抱歉;已编辑原帖。 - Ben Thul

1

我不知道MS-SQL的语法是否正确,但在MySQL中,查询看起来像这样:

DELETE FROM FriendsData WHERE fID 
       NOT IN ( SELECT fID FROM FriendsData 
                   GROUP BY UserID, FriendsUserID, IsSpecial, CreatedBy)

GROUP BY 子句中,您需要放置需要相同的列,以便将两个记录视为重复。

fID没有包含在聚合函数或group by子句中。以上SQL语句能直接使用吗? - shashi

0

尝试这个查询:

  select * from FriendsData f1, FriendsData f2
  Where f1.fID=f2.fID and f1.UserID  =f2.UserID  and f1.FriendsID  =f2.FriendsID

如果它返回了重复的行,那么用"Delete"替换Select *即可解决问题。

但是这样不会删除重复集合中的所有行吗?我认为要求是留下一个。 - Ben Thul

0

适用于Postgres:

DELETE from "FriendsData" where "fID" in
   (SELECT "fID" from
        (SELECT *, ROW_NUMBER() OVER(PARTITION BY "UserID", "FriendsID" ORDER BY  "fID") as rn
    FROM "FriendsData") as inner1
WHERE rn > 1);

嗨,感谢您的回答。很高兴它对您有效,但如果您能解释一下您做了什么以及如何解决最初的问题,那将对我们有所帮助! - Simas Joneliunas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接