当前位置:  开发笔记 > 编程语言 > 正文

如何删除重复的行?

如何解决《如何删除重复的行?》经验,为你挑选了31个好方法。

从相当大的SQL Server表中删除重复行的最佳方法是什么(即300,000多行)?

当然,由于RowID身份字段的存在,行不会是完美的重复.

MyTable的

RowID int not null identity(1,1) primary key,
Col1 varchar(20) not null,
Col2 varchar(2048) not null,
Col3 tinyint not null

Mark Bracket.. 1125

假设没有空,你GROUP BY的唯一列,并SELECTMIN (or MAX)RowId的为行,以保持.然后,只删除没有行id的所有内容:

DELETE FROM MyTable
LEFT OUTER JOIN (
   SELECT MIN(RowId) as RowId, Col1, Col2, Col3 
   FROM MyTable 
   GROUP BY Col1, Col2, Col3
) as KeepRows ON
   MyTable.RowId = KeepRows.RowId
WHERE
   KeepRows.RowId IS NULL

如果您有GUID而不是整数,则可以替换

MIN(RowId)

CONVERT(uniqueidentifier, MIN(CONVERT(char(36), MyGuidColumn)))

这会有效吗?`删除MyTable WHERE RowId NOT IN(选择MIN(RowId)FROM MyTable GROUP BY Col1,Col2,Col3);` (319认同)

@GeorgSchölly提供了一个优雅的答案.我在桌面上使用它,我的PHP bug创建了重复的行. (16认同)

@Martin,@ Georg:所以,我做了一个小测试.如下所述创建并填充了一个大表:http://sqlinthewild.co.za/index.php/2010/03/23/left-outer-join-vs-not-exists/然后生成两个SELECT,一个使用LEFT JOIN + WHERE IS NULL技术,另一个使用NOT IN.然后我继续执行计划,猜猜是什么?LEFT JOIN的查询成本为18%,NOT IN为82%,对我来说是一个惊喜.我可能做过一些我不应该做的事情,反之亦然,如果这是真的,我真的很想知道. (12认同)

抱歉,为什么`删除MyTable FROM MyTable`语法正确?在文档[here](http://technet.microsoft.com/en-us/library/ms189835(v = sql.110)中,我没有看到将"DELETE"作为选项放在"DELETE"之后. ASPX).对不起,如果这对其他人显而易见; 我只是想学习SQL的新手.更重要的是它为什么起作用:在那里包括表名的区别是什么? (12认同)

@Andriy - 在SQL Server中,"LEFT JOIN"效率低于"NOT EXISTS"http://sqlinthewild.co.za/index.php/2010/03/23/left-outer-join-vs-not-exists/同一网站还比较了"NOT IN"和"NOT EXISTS".http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/我认为"不存在"的表现最好.尽管可以避免,但这三个都将生成一个带有自联接的计划. (10认同)

@GeorgSchölly:这个陈述也适用于SQLite.谢谢! (3认同)

@levininja - 请参阅FROM table_source(允许在DELETE中使用FROM和JOIN的T-SQL扩展)和FROM table_alias(FROM是可选的); 第一个MyTable是table_alias,第二个是table_source. (3认同)

我知道来得很晚,但是http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/。如果这些列是可空的,则NOT IN的行为会不同,并且性能会非常差。这就是为什么我建议“不存在”的原因。 (2认同)

令人惊讶的是,考虑到这个问题的必要性,这是多么复杂 - 已经在几个需要这种事情的项目上工作过.核心SQL真的迫切需要一种更简单的方法,特别是考虑到这个问题和其他类似评论的评论和评论数量. (2认同)

@Georg的解决方案错误:您无法在FROM子句中指定目标表“产品”进行更新 (2认同)

要记住的一件事是,如果您的表处于活动状态(即始终插入新条目),则最好使用在当前时间之前结束的受限时间段运行此查询.如果外部查询而不是子查询读取新行,则自连接可能会导致不匹配.在这种情况下,可以删除非重复行. (2认同)

@Georg:对于一个包含很多行的表,其中只有极少数是应该删除的重复项,反转查询以减少IN参数的数量可以使查询更快:`DELETE FROM myTable WHERE id IN(SELECT id FROM myTable EXCEPT(SELECT MIN(id)id FROM myTable GROUP BY col1,col2,col3));` (2认同)


Martin Smith.. 743

另一种可行的方法是

; 

--Ensure that any immediately preceding statement is terminated with a semicolon above
WITH cte
     AS (SELECT ROW_NUMBER() OVER (PARTITION BY Col1, Col2, Col3 
                                       ORDER BY ( SELECT 0)) RN
         FROM   #MyTable)
DELETE FROM cte
WHERE  RN > 1;

我在ORDER BY (SELECT 0)上面使用,因为它是任意哪一行在出现平局时保留.

例如,为了保留最新的一个,RowID你可以使用ORDER BY RowID DESC

执行计划

对于此,执行计划通常比接受的答案更简单,更有效,因为它不需要自联接.

执行计划

但情况并非总是如此.GROUP BY可能首选解决方案的地方是优先选择散列聚合而不是流聚合的情况.

ROW_NUMBER,而该解决方案将永远给几乎相同的计划GROUP BY策略更加灵活.

执行计划

可能有利于散列聚合方法的因素是

分区列上没有有用的索引

相对较少的群体,每组中具有相对较多的重复

在第二种情况的极端版本​​中(如果每个组中都有很多重复的组很少),也可以考虑简单地插入行以保存到新表中然后TRUNCATE复制它们并将其复制回以最小化日志记录与删除行的比例非常高.



1> Mark Bracket..:

假设没有空,你GROUP BY的唯一列,并SELECTMIN (or MAX)RowId的为行,以保持.然后,只删除没有行id的所有内容:

DELETE FROM MyTable
LEFT OUTER JOIN (
   SELECT MIN(RowId) as RowId, Col1, Col2, Col3 
   FROM MyTable 
   GROUP BY Col1, Col2, Col3
) as KeepRows ON
   MyTable.RowId = KeepRows.RowId
WHERE
   KeepRows.RowId IS NULL

如果您有GUID而不是整数,则可以替换

MIN(RowId)

CONVERT(uniqueidentifier, MIN(CONVERT(char(36), MyGuidColumn)))


这会有效吗?`删除MyTable WHERE RowId NOT IN(选择MIN(RowId)FROM MyTable GROUP BY Col1,Col2,Col3);`
@GeorgSchölly提供了一个优雅的答案.我在桌面上使用它,我的PHP bug创建了重复的行.
@Martin,@ Georg:所以,我做了一个小测试.如下所述创建并填充了一个大表:http://sqlinthewild.co.za/index.php/2010/03/23/left-outer-join-vs-not-exists/然后生成两个SELECT,一个使用LEFT JOIN + WHERE IS NULL技术,另一个使用NOT IN.然后我继续执行计划,猜猜是什么?LEFT JOIN的查询成本为18%,NOT IN为82%,对我来说是一个惊喜.我可能做过一些我不应该做的事情,反之亦然,如果这是真的,我真的很想知道.
抱歉,为什么`删除MyTable FROM MyTable`语法正确?在文档[here](http://technet.microsoft.com/en-us/library/ms189835(v = sql.110)中,我没有看到将"DELETE"作为选项放在"DELETE"之后. ASPX).对不起,如果这对其他人显而易见; 我只是想学习SQL的新手.更重要的是它为什么起作用:在那里包括表名的区别是什么?
@Andriy - 在SQL Server中,"LEFT JOIN"效率低于"NOT EXISTS"http://sqlinthewild.co.za/index.php/2010/03/23/left-outer-join-vs-not-exists/同一网站还比较了"NOT IN"和"NOT EXISTS".http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/我认为"不存在"的表现最好.尽管可以避免,但这三个都将生成一个带有自联接的计划.
@GeorgSchölly:这个陈述也适用于SQLite.谢谢!
@levininja - 请参阅FROM table_source(允许在DELETE中使用FROM和JOIN的T-SQL扩展)和FROM table_alias(FROM是可选的); 第一个MyTable是table_alias,第二个是table_source.
我知道来得很晚,但是http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/。如果这些列是可空的,则NOT IN的行为会不同,并且性能会非常差。这就是为什么我建议“不存在”的原因。
令人惊讶的是,考虑到这个问题的必要性,这是多么复杂 - 已经在几个需要这种事情的项目上工作过.核心SQL真的迫切需要一种更简单的方法,特别是考虑到这个问题和其他类似评论的评论和评论数量.
@Georg的解决方案错误:您无法在FROM子句中指定目标表“产品”进行更新
要记住的一件事是,如果您的表处于活动状态(即始终插入新条目),则最好使用在当前时间之前结束的受限时间段运行此查询.如果外部查询而不是子查询读取新行,则自连接可能会导致不匹配.在这种情况下,可以删除非重复行.
@Georg:对于一个包含很多行的表,其中只有极少数是应该删除的重复项,反转查询以减少IN参数的数量可以使查询更快:`DELETE FROM myTable WHERE id IN(SELECT id FROM myTable EXCEPT(SELECT MIN(id)id FROM myTable GROUP BY col1,col2,col3));`

2> Martin Smith..:

另一种可行的方法是

; 

--Ensure that any immediately preceding statement is terminated with a semicolon above
WITH cte
     AS (SELECT ROW_NUMBER() OVER (PARTITION BY Col1, Col2, Col3 
                                       ORDER BY ( SELECT 0)) RN
         FROM   #MyTable)
DELETE FROM cte
WHERE  RN > 1;

我在ORDER BY (SELECT 0)上面使用,因为它是任意哪一行在出现平局时保留.

例如,为了保留最新的一个,RowID你可以使用ORDER BY RowID DESC

执行计划

对于此,执行计划通常比接受的答案更简单,更有效,因为它不需要自联接.

执行计划

但情况并非总是如此.GROUP BY可能首选解决方案的地方是优先选择散列聚合而不是流聚合的情况.

ROW_NUMBER,而该解决方案将永远给几乎相同的计划GROUP BY策略更加灵活.

执行计划

可能有利于散列聚合方法的因素是

分区列上没有有用的索引

相对较少的群体,每组中具有相对较多的重复

在第二种情况的极端版本​​中(如果每个组中都有很多重复的组很少),也可以考虑简单地插入行以保存到新表中然后TRUNCATE复制它们并将其复制回以最小化日志记录与删除行的比例非常高.


如果我可以添加:接受的答案不适用于使用`uniqueidentifier`的表.这个更简单,适用于任何桌子.谢谢马丁.
与接受的答案不同,这也适用于没有键(`RowId`)进行比较的表.
这是一个非常棒的答案!当我意识到那里有重复之前我删除了旧的PK时它起了作用.+100
我建议在DBA.SE上询问并回答这个问题(带有这个答案).然后我们可以将它添加到[我们的规范答案列表](http://meta.dba.stackexchange.com/q/708/2660).
另一方面,这个版本不适用于所有SQL Server版本
@David - 它适用于2005年以上.现在是2015年.

3> Jon Galloway..:

有一篇关于删除 Microsoft支持站点上的重复项的文章.这是相当保守的 - 他们让你在不同的步骤中做所有事情 - 但它应该适用于大表.

我过去曾经使用过自联接来做这个,虽然它可能会被HAVING子句搞定:

DELETE dupes
FROM MyTable dupes, MyTable fullTable
WHERE dupes.dupField = fullTable.dupField 
AND dupes.secondDupField = fullTable.secondDupField 
AND dupes.uniqueField > fullTable.uniqueField



4> 小智..:

以下查询对于删除重复行很有用.本例中的表具有ID作为标识列和具有重复数据的列是Column1,Column2并且Column3.

DELETE FROM TableName
WHERE  ID NOT IN (SELECT MAX(ID)
                  FROM   TableName
                  GROUP  BY Column1,
                            Column2,
                            Column3
                  /*Even if ID is not null-able SQL Server treats MAX(ID) as potentially
                    nullable. Because of semantics of NOT IN (NULL) including the clause
                    below can simplify the plan*/
                  HAVING MAX(ID) IS NOT NULL) 

下面的脚本说明用法GROUP BY,HAVING,ORDER BY在一个查询中,并返回带有重复列,其计结果.

SELECT YourColumnName,
       COUNT(*) TotalCount
FROM   YourTableName
GROUP  BY YourColumnName
HAVING COUNT(*) > 1
ORDER  BY COUNT(*) DESC 


@parvus - 问题是标记SQL Server而不是MySQL.SQL Server中的语法很好.此外,MySQL在优化子查询方面非常糟糕[参见此处](http://stackoverflow.com/q/3417074/73226).这个答案在SQL Server中很好.事实上,"NOT IN"通常比"OUTER JOIN ... NULL"表现得更好.我会在查询中添加一个"HAVING MAX(ID)IS NOT NULL",尽管从语义上讲它不应该是必要的,因为这可以改进计划[这里的例子](http://dba.stackexchange.com/questions/31135 /删除重复的 - 记录 - 时 - 使用文本,数据类型/ 31145#31145)
在PostgreSQL 8.4中运行良好.

5> SoftwareGeek..:
delete t1
from table t1, table t2
where t1.columnA = t2.columnA
and t1.rowid>t2.rowid

Postgres的:

delete
from table t1
using table t2
where t1.columnA = t2.columnA
and t1.rowid > t2.rowid


@Lankymart因为postgres用户也来了。看这个答案的分数。
我已经在一些受欢迎的SQL问题中看到了这一点,例如[here](/sf/ask/17360801/),[here]( /sf/ask/17360801/)和[here](/sf/ask/17360801/ / concatenate-many-rows-in-single-text-string)。OP得到了他的回答,其他所有人也得到了一些帮助。没问题,恕我直言。

6> Jithin Shaji..:
DELETE LU 
FROM   (SELECT *, 
               Row_number() 
                 OVER ( 
                   partition BY col1, col1, col3 
                   ORDER BY rowid DESC) [Row] 
        FROM   mytable) LU 
WHERE  [row] > 1 



7> Syed Mohamed..:

这将删除第一行以外的重复行

DELETE
FROM
    Mytable
WHERE
    RowID NOT IN (
        SELECT
            MIN(RowID)
        FROM
            Mytable
        GROUP BY
            Col1,
            Col2,
            Col3
    )

参考(http://www.codeproject.com/Articles/157977/Remove-Duplicate-Rows-from-a-Table-in-SQL-Server)


对于mysql,它将给出错误:错误代码:1093.您不能在FROM子句中为更新指定目标表'Mytable'.但这个小改动将适用于mysql:DELETE FROM Mytable WHERE RowID NOT IN(SELECT ID FROM(SELECT MIN(RowID)AS ID from Mytable GROUP BY Col1,Col2,Col3)AS TEMP)

8> Shamseer K..:

我更喜欢CTE从sql server表中删除重复的行

强烈建议遵循这篇文章:: http://codaffection.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)



9> 小智..:

获取重复行:

SELECT
name, email, COUNT(*)
FROM 
users
GROUP BY
name, email
HAVING COUNT(*) > 1

删除重复行:

DELETE users 
WHERE rowid NOT IN 
(SELECT MIN(rowid)
FROM users
GROUP BY name, email);      



10> 小智..:

快速和脏删除精确重复的行(对于小表):

select  distinct * into t2 from t1;
delete from t1;
insert into t1 select *  from t2;
drop table t2;


请注意,该问题实际上指定了非精确复制(dueto row id).

11> James Errico..:

我更喜欢子查询\具有count(*)> 1的内部连接解决方​​案,因为我发现它更容易阅读,并且很容易变成SELECT语句来验证在运行之前将删除的内容.

--DELETE FROM table1 
--WHERE id IN ( 
     SELECT MIN(id) FROM table1 
     GROUP BY col1, col2, col3 
     -- could add a WHERE clause here to further filter
     HAVING count(*) > 1
--)


这不会清理所有重复项.如果你有3行是重复的,它只会选择具有MIN(id)的行,并删除那一行,留下两行是重复的.
您只返回id最低的那个,基于select子句中的min(id).
取消注释查询的第一行,第二行和最后一行.
尽管如此,我最后一次又一次地重复使用这个语句,以便它实际上取得进展,而不是让连接超时或计算机进入睡眠状态.我将其更改为"MAX(id)"以消除后者的重复,并将"LIMIT 1000000"添加到内部查询中,这样就不必扫描整个表.这显示了比其他答案快得多的进展,这似乎会持续数小时.将表修剪为可管理的大小后,您可以完成其他查询.提示:确保col1/col2/col3具有group by的索引.

12> 小智..:
SELECT  DISTINCT *
      INTO tempdb.dbo.tmpTable
FROM myTable

TRUNCATE TABLE myTable
INSERT INTO myTable SELECT * FROM tempdb.dbo.tmpTable
DROP TABLE tempdb.dbo.tmpTable


如果您对myTable有外键引用,则截断将不起作用.

13> Ruben Versch..:

我想我会分享我的解决方案,因为它在特殊情况下有效.我的情况下,具有重复值的表没有外键(因为这些值是从另一个数据库复制的).

begin transaction
-- create temp table with identical structure as source table
Select * Into #temp From tableName Where 1 = 2

-- insert distinct values into temp
insert into #temp 
select distinct * 
from  tableName

-- delete from source
delete from tableName 

-- insert into source from temp
insert into tableName 
select * 
from #temp

rollback transaction
-- if this works, change rollback to commit and execute again to keep you changes!!

PS:在处理这样的事情时,我总是使用一个事务,这不仅可以确保所有内容都作为一个整体执行,而且还允许我在不冒任何风险的情况下进行测试.但是当然你应该备份,以确保......



14> Ostati..:

使用CTE.我们的想法是加入一个或多个形成重复记录的列,然后删除您喜欢的任何一个:

;with cte as (
    select 
        min(PrimaryKey) as PrimaryKey
        UniqueColumn1,
        UniqueColumn2
    from dbo.DuplicatesTable 
    group by
        UniqueColumn1, UniqueColumn1
    having count(*) > 1
)
delete d
from dbo.DuplicatesTable d 
inner join cte on 
    d.PrimaryKey > cte.PrimaryKey and
    d.UniqueColumn1 = cte.UniqueColumn1 and 
    d.UniqueColumn2 = cte.UniqueColumn2;



15> Draško..:

这个查询对我来说表现非常好:

DELETE tbl
FROM
    MyTable tbl
WHERE
    EXISTS (
        SELECT
            *
        FROM
            MyTable tbl2
        WHERE
            tbl2.SameValue = tbl.SameValue
        AND tbl.IdUniqueValue < tbl2.IdUniqueValue
    )

它从2M的表中删除了超过30秒的1M行(50%重复)



16> Nitish Paree..:

另外一个简单的解决方案可以在这里粘贴的链接找到.这个容易掌握,似乎对大多数类似的问题都有效.它适用于SQL Server,但使用的概念是可接受的.

以下是链接页面的相关部分:

考虑这些数据:

EMPLOYEE_ID ATTENDANCE_DATE
A001    2011-01-01
A001    2011-01-01
A002    2011-01-01
A002    2011-01-01
A002    2011-01-01
A003    2011-01-01

那么我们如何删除那些重复数据呢?

首先,使用以下代码在该表中插入标识列:

ALTER TABLE dbo.ATTENDANCE ADD AUTOID INT IDENTITY(1,1)  

使用以下代码解决它:

DELETE FROM dbo.ATTENDANCE WHERE AUTOID NOT IN (SELECT MIN(AUTOID) _
    FROM dbo.ATTENDANCE GROUP BY EMPLOYEE_ID,ATTENDANCE_DATE) 



17> Craig..:

这是关于删除重复项的另一篇好文章.

它讨论了为什么它很难:" SQL基于关系代数,并且重复在关系代数中不会发生,因为在集合中不允许重复. "

临时表解决方案,以及两个mysql示例.

将来您是要在数据库级别还是从应用程序的角度来防止它.我建议数据库级别,因为您的数据库应该负责维护参照完整性,开发人员只会导致问题;)



18> Jacob Proffi..:

行,可以.使用临时表.如果你想要一个"工作"的单一,不是非常高效的陈述,你可以使用:

DELETE FROM MyTable WHERE NOT RowID IN
    (SELECT 
        (SELECT TOP 1 RowID FROM MyTable mt2 
        WHERE mt2.Col1 = mt.Col1 
        AND mt2.Col2 = mt.Col2 
        AND mt2.Col3 = mt.Col3) 
    FROM MyTable mt)

基本上,对于表中的每一行,子选择查找与所考虑的行完全相同的所有行的顶部RowID.因此,您最终会得到一个表示"原始"非重复行的RowID列表.



19> chrismar035..:

我有一个表,我需要保留不重复的行.我不确定速度或效率.

DELETE FROM myTable WHERE RowID IN (
  SELECT MIN(RowID) AS IDNo FROM myTable
  GROUP BY Col1, Col2, Col3
  HAVING COUNT(*) = 2 )


这假定最多有1个重复.

20> Haris..:

用这个

WITH tblTemp as
(
SELECT ROW_NUMBER() Over(PARTITION BY Name,Department ORDER BY Name)
   As RowNumber,* FROM 
)
DELETE FROM tblTemp where RowNumber >1



21> İsmail Yavuz..:

另一种方法是创建一个具有相同字段和唯一索引的新表.然后将所有数据从旧表移动到新表.自动SQL SERVER忽略(如果存在重复值,还有一个关于该怎么做的选项:ignore,interrupt或sth)重复值.所以我们有相同的表没有重复的行.如果您不想要唯一索引,则可以在传输数据之后删除它.

特别是对于较大的表,您可以使用DTS(SSIS包来导入/导出数据),以便将所有数据快速传输到新的唯一索引表.对于700万行,它只需要几分钟.



22> 小智..:

    创建具有相同结构的新空白表

    像这样执行查询

    INSERT INTO tc_category1
    SELECT *
    FROM tc_category
    GROUP BY category_id, application_id
    HAVING count(*) > 1
    

    然后执行此查询

    INSERT INTO tc_category1
    SELECT *
    FROM tc_category
    GROUP BY category_id, application_id
    HAVING count(*) = 1
    



23> 小智..:

通过使用以下查询,我们可以根据单列或多列删除重复记录.以下查询是基于两列删除.表名是:testing和列名empno,empname

DELETE FROM testing WHERE empno not IN (SELECT empno FROM (SELECT empno, ROW_NUMBER() OVER (PARTITION BY empno ORDER BY empno) 
AS [ItemNumber] FROM testing) a WHERE ItemNumber > 1)
or empname not in
(select empname from (select empname,row_number() over(PARTITION BY empno ORDER BY empno) 
AS [ItemNumber] FROM testing) a WHERE ItemNumber > 1)



24> 小智..:

这是删除重复记录的最简单方法

 DELETE FROM tblemp WHERE id IN 
 (
  SELECT MIN(id) FROM tblemp
   GROUP BY  title HAVING COUNT(id)>1
 )

http://askme.indianyouth.info/details/how-to-dumplicate-record-from-table-in-using-sql-105



25> DrPizza..:

从应用程序级别(不幸的).我同意防止重复的正确方法是在数据库级别通过使用唯一索引,但在SQL Server 2005中,索引只允许900字节,我的varchar(2048)字段将其吹走.

我不知道它的表现如何,但我认为你可以编写一个触发器来强制执行此操作,即使你不能直接使用索引.就像是:

-- given a table stories(story_id int not null primary key, story varchar(max) not null)
CREATE TRIGGER prevent_plagiarism 
ON stories 
after INSERT, UPDATE 
AS 
    DECLARE @cnt AS INT 

    SELECT @cnt = Count(*) 
    FROM   stories 
           INNER JOIN inserted 
                   ON ( stories.story = inserted.story 
                        AND stories.story_id != inserted.story_id ) 

    IF @cnt > 0 
      BEGIN 
          RAISERROR('plagiarism detected',16,1) 

          ROLLBACK TRANSACTION 
      END 

另外,varchar(2048)对我来说听起来很腥(生活中有些东西是2048字节,但这种情况非常罕见); 它真的不是varchar(max)吗?



26> 小智..:

我会提到这种方法,它可能会有所帮助,适用于所有SQL服务器:通常只有一个 - 两个重复,并且Ids和重复计数是已知的.在这种情况下:

SET ROWCOUNT 1 -- or set to number of rows to be deleted
delete from myTable where RowId = DuplicatedID
SET ROWCOUNT 0



27> 小智..:
DELETE
FROM
    table_name T1
WHERE
    rowid > (
        SELECT
            min(rowid)
        FROM
            table_name T2
        WHERE
            T1.column_name = T2.column_name
    );



28> AnandPhadke..:
CREATE TABLE car(Id int identity(1,1), PersonId int, CarId int)

INSERT INTO car(PersonId,CarId)
VALUES(1,2),(1,3),(1,2),(2,4)

--SELECT * FROM car

;WITH CTE as(
SELECT ROW_NUMBER() over (PARTITION BY personid,carid order by personid,carid) as rn,Id,PersonID,CarId from car)

DELETE FROM car where Id in(SELECT Id FROM CTE WHERE rn>1)



29> Jayron Soare..:
DELETE 
FROM MyTable
WHERE NOT EXISTS (
              SELECT min(RowID)
              FROM Mytable
              WHERE (SELECT RowID 
                     FROM Mytable
                     GROUP BY Col1, Col2, Col3
                     ))
               );



30> Lauri Lubi..:

我想要预览要删除的行,并控制要保留的重复行.见http://developer.azurewebsites.net/2014/09/better-sql-group-by-find-duplicate-data/

with MYCTE as (
  SELECT ROW_NUMBER() OVER (
    PARTITION BY DuplicateKey1
                ,DuplicateKey2 -- optional
    ORDER BY CreatedAt -- the first row among duplicates will be kept, other rows will be removed
  ) RN
  FROM MyTable
)
DELETE FROM MYCTE
WHERE RN > 1



31> yuvi..:

另一种方法: -

DELETE A
FROM   TABLE A,
       TABLE B
WHERE  A.COL1 = B.COL1
       AND A.COL2 = B.COL2
       AND A.UNIQUEFIELD > B.UNIQUEFIELD 

推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有