如何删除sql server中的重复行?
如何删除没有唯一行ID的重复行?
我的桌子是
col1 col2 col3 col4 col5 col6 col7 john 1 1 1 1 1 1 john 1 1 1 1 1 1 sally 2 2 2 2 2 2 sally 2 2 2 2 2 2
重复删除后,我想留下以下内容:
john 1 1 1 1 1 1 sally 2 2 2 2 2 2
我已经尝试了几个查询,但我认为他们依赖于行ID,因为我没有得到所需的结果。 例如:
DELETE FROM table WHERE col1 IN ( SELECT id FROM table GROUP BY id HAVING ( COUNT(col1) > 1 ) )
我喜欢CTE和ROW_NUMBER
因为这两个组合允许我们看到哪些行被删除(或更新),因此只需将DELETE FROM CTE...
更改为SELECT * FROM CTE
:
WITH CTE AS( SELECT [col1], [col2], [col3], [col4], [col5], [col6], [col7], RN = ROW_NUMBER()OVER(PARTITION BY col1 ORDER BY col1) FROM dbo.Table1 ) DELETE FROM CTE WHERE RN > 1
DEMO (结果是不同的;我认为这是由于你的错字)
COL1 COL2 COL3 COL4 COL5 COL6 COL7 john 1 1 1 1 1 1 sally 2 2 2 2 2 2
这个例子决定了一个列col1
重复,因为PARTITION BY col1
。 如果你想包含多个列,只需将它们添加到PARTITION BY
:
ROW_NUMBER()OVER(PARTITION BY Col1, Col2, ... ORDER BY OrderColumn)
我宁愿CTE从sql server表中删除重复的行
强烈build议遵循这篇文章:: http://dotnetmob.com/sql-server-article/delete-duplicate-rows-in-sql-server/
保持原来的
WITH CTE AS ( SELECT *,ROW_NUMBER() OVER (PARTITION BY col1,col2,col3 ORDER BY col1,col2,col3) AS RN FROM MyTable ) DELETE FROM CTE WHERE RN<>1
不保留原创
WITH CTE AS (SELECT *,R=RANK() OVER (ORDER BY col1,col2,col3) FROM MyTable) DELETE CTE WHERE R IN (SELECT R FROM CTE GROUP BY R HAVING COUNT(*)>1)
DELETE from search where id not in ( select min(id) from search group by url having count(*)=1 union SELECT min(id) FROM search group by url having count(*) > 1 )
如果不使用CTE
和ROW_NUMBER()
,只需使用MAX
函数使用group来删除logging即可
DELETE FROM MyDuplicateTable WHERE ID NOT IN ( SELECT MAX(ID) FROM MyDuplicateTable GROUP BY DuplicateColumn1, DuplicateColumn2, DuplicateColumn3)
微软有一个清晰的指导如何删除重复。 检查出http://support.microsoft.com/kb/139444
简而言之,下面是删除重复行时最简单的方法:
SET rowcount 1; DELETE FROM t1 WHERE myprimarykey=1;
myprimarykey是行的标识符。
我将rowcount设置为1,因为我只有两行重复。 如果我有3行重复,那么我会将行数设置为2,这样它会删除它所看到的前两个,只在表t1中留下一行。
希望它能帮助任何人
- selectDISTINCTlogging到新表中
- 截断旧表
- 将新表合并回旧表
请看下面的删除方法。
Declare @table table (col1 varchar(10),col2 int,col3 int, col4 int, col5 int, col6 int, col7 int) Insert into @table values ('john',1,1,1,1,1,1), ('john',1,1,1,1,1,1), ('sally',2,2,2,2,2,2), ('sally',2,2,2,2,2,2)
创build一个名为@table
的示例表并使用给定的数据加载它。
Delete aliasName from ( Select *, ROW_NUMBER() over (Partition by col1,col2,col3,col4,col5,col6,col7 order by col1) as rowNumber From @table) aliasName Where rowNumber > 1 Select * from @table
注意:如果您要Partition by
所有列,那么order by
并不重要。
我知道,这个问题是三年前提出的,我的回答是Tim发布的另一个版本,但是发布这个问题对任何人都有帮助。
如果你没有引用,像外键,你可以这样做。 在testing概念certificate和testing数据重复时,我做了很多工作。
SELECT DISTINCT [col1],[col2],[col3],[col4],[col5],[col6],[col7]
INTO [newTable]
;
进入对象浏览器并删除旧的表。
用旧的表格名称重新命名新的表格。
-- this query will keep only one instance of a duplicate record. ;WITH cte AS (SELECT ROW_NUMBER() OVER (PARTITION BY col1, col2, col3-- based on what? --can be multiple columns ORDER BY ( SELECT 0)) RN FROM Mytable) delete FROM cte WHERE RN > 1
另一种删除已公布的行的方法是在不丢失信息的情况下进行的,如下所示:
delete from dublicated_table t1 (nolock) join ( select t2.dublicated_field , min(len(t2.field_kept)) as min_field_kept from dublicated_table t2 (nolock) group by t2.dublicated_field having COUNT(*)>1 ) t3 on t1.dublicated_field=t3.dublicated_field and len(t1.field_kept)=t3.min_field_kept
with myCTE as ( select productName,ROW_NUMBER() over(PARTITION BY productName order by slno) as Duplicate from productDetails ) Delete from myCTE where Duplicate>1
删除重复的想法涉及
- a)保护那些不重复的行
- b)保留合格的许多行中的一个作为重复。
一步步
- 1)首先确定那些满足重复定义的行并将它们插入到临时表中,例如#tableAll。
- 2)select非重复(单行)或不同的行到临时表say #tableUnique。
- 3)从源表中删除连接#tableAll删除重复项。
- 4)从#tableUnique中插入所有行的源表。
- 5)删除#tableAll和#tableUnique
如果你能find重复的行数,例如你有n个重复的行,那么使用这个命令
SET rowcount n-1 DELETE FROM your_table WHERE (spacial condition)
更多的信息,我build议这个