检查SQL Server中的重复数据

时间:2011-06-02 04:35:09

标签: sql sql-server sql-server-2008

请不要问我为什么,但是有很多重复的数据,其中每个字段都是重复的。

例如

alex, 1
alex, 1
liza, 32
hary, 34

我需要从此表中删除alex, 1

之一

我知道这个算法会非常低效,但没关系。我需要删除重复的数据。

最好的方法是什么?请记住,我没有2个字段,实际上我有大约10个字段需要检查。

5 个答案:

答案 0 :(得分:6)

正如你所说,是的,效率非常低,但你可以试试

DECLARE @TestTable TABLE(
        Name VARCHAR(20),
        SomeVal INT
)
INSERT INTO @TestTable SELECT 'alex', 1
INSERT INTO @TestTable SELECT 'alex', 1
INSERT INTO @TestTable SELECT 'liza', 32
INSERT INTO @TestTable SELECT 'hary', 34

SELECT  *
FROM    @TestTable

;WITH DuplicateVals AS (
    SELECT  *,
            ROW_NUMBER() OVER (PARTITION BY Name, SomeVal ORDER BY (SELECT NULL)) RowID
    FROM    @TestTable
)
DELETE FROM DuplicateVals WHERE RowID > 1

SELECT *
FROM    @TestTable

答案 1 :(得分:3)

我理解这并没有回答具体问题(消除SAME表中的欺骗),但我提供的解决方案因为它非常快,可能对作者最有效。

快速解决方案,如果您不介意创建新表,请使用名为NewTable的相同模式创建一个新表。

执行此SQL

 Insert into NewTable
 Select 
   name, 
   num 
 from
   OldTable
 group by
   name,
   num

只需在select和group by子句中包含每个字段名称。

答案 2 :(得分:2)

create table DuplicateTable(name varchar(10), number int)

insert DuplicateTable
values
    ('alex', 1),
    ('alex', 1),
    ('liza', 32),
    ('hary', 34);

with cte
as
(
    select *, row_number() over(partition by name, number order by name) RowNumber
    from DuplicateTable
)
delete cte
where RowNumber > 1

答案 3 :(得分:2)

方法A. 您可以使用

获取数据的重复数据删除版本
SELECT field1, field2, ...
INTO Deduped
FROM Source
GROUP BY field1, field2, ...

例如,对于您的样本数据,

SELECT name, number
FROM Source
GROUP BY name, number

产量

alex    1
hary    34
liza    32

然后只需删除旧表,然后重命名新表。当然,有许多奇特的就地解决方案,但这是最明智的方法。

方法B。就地方法是创建主键并以这种方式删除重复项。例如,您可以

ALTER TABLE Source ADD sid INT IDENTITY(1,1);

使Source看起来像这样

alex    1   1
alex    1   2
liza    32  3
hary    34  4

然后你可以使用

DELETE FROM Source
WHERE  sid NOT IN
  (SELECT MIN(sid)
   FROM  Source
   GROUP BY name, number)

将产生所需的结果。当然,“NOT IN”并不是最有效的,但它会完成这项工作。或者,您可以LEFT JOIN分组表(可能存储在TEMP表中),并以这种方式执行DELETE。

答案 4 :(得分:2)

需要主键(或唯一索引)的不同解决方案: 假设您有一个表your_table(id - PK, name, and num)

DELETE 
FROM your_table     
FROM your_table AS t2
WHERE 
(select  COUNT(*) FROM your_table y 
  where t2.name = y.name and  t2.num = y.num) >1
AND t2.id != 
(SELECT top 1 id FROM your_table z 
 WHERE t2.name = z.name and  t2.num = z.num);

我假设名称和数字为NOT NULL,如果它们可以包含NULL值,则需要在子查询中更改where