2015-11-13 37 views
0

某些行共享相同的主键(ID),但行的其余部分可能不同。例如,如何删除重复行

ID Age Info 
2 21 2763 
2 21 6276 
3 31 82756 

在这种情况下,第一行和第二行都具有相同的ID和年龄,但信息不同。我想要做的重复ID行是随机保留其中一个,并删除其他人。我在我的数据集中有这么多种记录,所以我无法逐一删除它们。有没有解决方法?由于

+2

什么是RDBMS? – SQLChao

+0

哪个是你在这张表中的主键? – Adish

+0

在这个例子中@Adish PK是ID。谢谢 –

回答

0

我认为你在寻找这样的事情:

delete from TableName where info not in 
(select min(info) from TableName group by ID,Age); 

尝试select语句首先要确保它返回正确的行,然后删除部分添加到它

+0

让我试试吧!感谢您的答复! –

+1

这只会在'info'是唯一的时候才起作用。一行ID = 2,Info = 82756会抛弃它。 –

+0

正确,每个示例的假设是Info对于每个分组标识和年龄都是唯一的。 –

1

试试这个:

DELETE t1 
FROM mytable AS t1 
INNER JOIN mytable AS t2 
ON t1.ID = t2.ID AND t1.Age = t2.Age AND t1.Info > t2.Info 

以上应该在MySQL,SQL Server中工作。该语句将删除(ID, Age)切片中的所有行,但会删除值中最小的那个。

注意:上述工作规定Info值是唯一的每(ID, Age)切片。

+0

感谢您的回答,t1和t2是什么? –

+0

@GavinNiu他们是表别名 –

+0

这不会删除ID匹配的行,但Age不会。这不会删除所有三列相同的行。 – Adish

0

我会建议一个基于集合的解决方案,但我无法照顾所有3行相同的行。因此建议使用ROWCOUNT和while循环的解决方案。 ROWCOUNT将确保一次只删除一条记录。 while循环是这样的,你不必一个一个地手动完成。

SET ROWCOUNT 1 

DECLARE @ctr INT 
SELECT TOP 1 @ctr = COUNT(*) FROM table GROUP BY ID HAVING COUNT(*) > 1 ORDER BY COUNT(*) desc 
SELECT @ctr 
WHILE @ctr > 1 
BEGIN 
    DELETE FROM table WHERE ID IN (SELECT ID FROM table GROUP BY ID HAVING COUNT(*) > 1) 
    SELECT @ctr = NULL 
    SELECT TOP 1 @ctr = COUNT(*) FROM table GROUP BY ID HAVING COUNT(*) > 1 ORDER BY COUNT(*) desc 
If @Ctr IS NULL 
    Break 
ELSE 
    Continue 
END 
SET ROWCOUNT 0 

您可以在删除语句中更改order by语句以满足您的要求。

+0

试试这个。执行前执行备份。 – Adish

1

用窗函数:

;with cte as(select *, row_number() over(partition by id order by info) rn 
      from table) 
delete from cte where rn <> 1