2011-11-29 69 views
2

我有大表(〜1,000,000行),可能包含重复的值。删除大表中的重复行

该表包含两列(例如col a,col b),它们共同表示唯一键,ID和最后更新日期。

例如我可以有如下表格:

id | a | b |更新

1 | jon |史密斯| 1/1

2 | don |史密斯| 2/5

3 | bob |大卫| 1/1

4 | dan |刘易斯| 3/1

5 | bob |大卫| 3/1

正如您可以看到id 3和5那样,该表在a列和b列中都包含相同的值。 我想删除包含这种重复的行,但保留最后一次更新的行。

对于这个例子,我将在删除后有这张表: id | a | b |更新

1 | jon |史密斯| 1/1

2 | don |史密斯| 2/5

4 | dan |刘易斯| 3/1

5 | bob |戴维斯| 3/1

(ID = 3删除,因为我已经有一个摆锤=和b =戴维斯在行其中id = 5,该行中的更新是高于所述一个被删除的行中)

回答

2
delete from MyTable 
where exists (
    select 1 from MyTable t2 
    where MyTable.a=t2.a and MyTable.b=t2.b and MyTable.upd<t2.upd 
) 
0

您需要在WHERE子句中执行两个自引用。第一个标识重复的行,第二个将确保您没有删除最新的版本。

DELETE 
FROM  TestCase 
WHERE EXISTS (
    -- Where there's more than one 
    SELECT 1 
    FROM  TestCase AS Reference 
    WHERE TestCase.a = Reference.a 
     AND TestCase.b = Reference.b 
     AND TestCase.[update] <> Reference.[update] 
    ) 
    AND TestCase.[update] <> (
    -- and this isn't the most recent 
    SELECT Max (Reference2.[update]) 
    FROM  TestCase AS Reference2 
    WHERE TestCase.a = Reference2.a 
     AND TestCase.b = Reference2.b 
    GROUP BY Reference2.a, 
      Reference2.b 
    ) 
+1

一个自我引用应该是足够的,因为最新的更新的不平等就足以阻止行从与自身匹配起来。 – dasblinkenlight

+1

你说得对,dasblinkenlight。在这样的大型桌面上,性能增益会很大。荣誉。 ;) –

1

下面一个应该工作。

DELETE FROM MYTABLE WHERE ID IN( SELECT M1.ID FROM MYTABLE M1, MYTABLE M2 WHERE M1.A = M2.A AND M1.B = M2.B AND M1.ID < M2.ID);