从大型数据集中删除重复项(> 100Mio行)

use*_*440 4 t-sql sql-server duplicates sql-server-2008

我知道这个主题在此之前出现了很多次,但是没有一个建议的解决方案适用于我的数据集,因为我的笔记本电脑由于内存问题或完全存储而停止计算.

我的表看起来如下,并有108Mio行:

Col1       |Col2   |  Col3           |Col4   |SICComb |  NameComb 

Case New   |3523   |  Alexander      |6799   |67993523| AlexanderCase New 
Case New   |3523   |  Undisclosed    |6799   |67993523| Case NewUndisclosed 
Undisclosed|6799   |  Case New       |3523   |67993523| Case NewUndisclosed 
Case New   |3523   |  Undisclosed    |6799   |67993523| Case NewUndisclosed 
SmartCard  |3674   |  NEC            |7373   |73733674| NECSmartCard 
SmartCard  |3674   |  Virtual NetComm|7373   |73733674| SmartCardVirtual NetComm 
SmartCard  |3674   |  NEC            |7373   |73733674| NECSmartCard
Run Code Online (Sandbox Code Playgroud)

独特的列是SICCombNameComb.我尝试添加一个主键:

ALTER TABLE dbo.test ADD ID INT IDENTITY(1,1)
Run Code Online (Sandbox Code Playgroud)

但是整数30只会在新的分钟内填满我的存储空间.

哪个是从表中删除重复项的最快最有效的方法?

Rom*_*kar 7

如果您使用的是SQL Server,则可以使用公用表表达式中的delete:

with cte as (
    select row_number() over(partition by SICComb, NameComb order by Col1) as row_num
    from Table1
)
delete
from cte
where row_num > 1
Run Code Online (Sandbox Code Playgroud)

这里所有行都将被编号,您为每个唯一的SICComb+ 组合获得自己的序列NameComb.您可以通过order byover子句中选择要选择要删除的行.

  • @ShahgholiArdalan不要触摸我的代码.我相信在SQL中使用大字母的传统应该消失,我总是格式化我的代码以便于阅读,不要让我的答案变得更糟! (3认同)

Gor*_*off 2

一般来说,从表中删除重复项的最快方法是将没有重复项的记录插入到临时表中,截断原始表并将它们重新插入。

这是使用 SQL Server 语法的想法:

select distinct t.*
into #temptable
from t;

truncate table t;

insert into t
    select tt.*
    from #temptable;
Run Code Online (Sandbox Code Playgroud)

当然,这很大程度上取决于第一步的速度有多快。并且,您需要有空间来存储同一个表的两个副本。

请注意,创建临时表的语法因数据库而异。create table as有些使用而不是的语法select into

编辑:

您的身份插入错误很麻烦。我认为您需要从不同的列列表中删除身份。或者做:

select min(<identity col>), <all other columns>
from t
group by <all other columns>
Run Code Online (Sandbox Code Playgroud)

如果您有一个标识列,则不会有重复项(根据定义)。

最后,您需要决定行的 ID。如果您可以为行生成新的 id,则只需将标识列保留在插入的列列表之外即可:

insert into t(<all other columns>)
    select <all other columns>;
Run Code Online (Sandbox Code Playgroud)

如果您需要旧的标识值(最小值即可),请关闭标识插入并执行以下操作:

insert into t(<all columns including identity>)
    select <all columns including identity>;
Run Code Online (Sandbox Code Playgroud)