2011-01-27 112 views
3

我有一个(大〜1个000 000行)表可能含有重复行(可能的空值)。删除重复行#2

我想要做的是这样的:

  1. 只选择distinc行。
  2. 删除重复'id'字段的行。

让我们有一个表:

id | a | b  
1 | 2 | 3  
2 | 8 | 7  
3 | 9 | 10  
2 | 8 | 7  
3 | 20| 12 

我想要得到的是:

ID为2
id | a | b  
1 | 2 | 3  
2 | 8 | 7 

行中的一个副本被保存,而id为3行被删除。

我在想:

  1. SELECT DISTINCT id, a, b FROM table;只获取不同的行。
  2. 以某种方式筛选(1)的结果以删除重复的ID。

什么是接近这一目标的最佳方式是什么?

+2

我很好奇,你发现了什么,当你进入`sql中删除重复rows`到SO搜索框。你有没有得到我所做的四十页结果? :-)很抱歉,无法抗拒的刺拳:看http://stackoverflow.com/search?q=sql+remove+duplicate+rows – paxdiablo 2011-01-27 12:43:07

+1

行2重复两次,它的下面列出,但第1行不重复两次它也在下面列出。这有点令人困惑,我假设你的意思是只有第1行,或者第1行和第3行? – Neil 2011-01-27 12:43:13

+0

@尼尔,我认为`2`因为内容完全相同而幸存下来。因为这两个记录不同(换句话说,如果所有副本都是相同的,保留一个ID副本,否则抛出),这可能会使我的smarmy评论不准确,因为这似乎是一个相当特殊的案件:-)如果事实真相如此,向道歉。 – paxdiablo 2011-01-27 12:44:49

回答

0

切赫,它看起来像每评论,你想有一个组合...

包括: 的所有行ID发生只有一次 ID出现的所有行不止一次 - 与记录中的所有其他字段相同

EXCLUDE: ID出现超过一次的任何行 - AND其他领域不完全匹配。

select ID, min(a) a, min(b) b 
    from YourTable 
    group by ID 
    having min(a) = max(a) 
     and min(b) = max(b) 

如果从A和B相比有更多的列不谈,只是各自的值添加到选择字段列表和相应的拥有。从您所提供的数据样本,该值从查询返回将

ID MIN(A) MIN(B) Having MIN(A) MAX(A) MIN(B) MAX(B) 
1 2  3    2  2  3  3 
2 8  7    8  8  7  7 
3 9  10    9  20  10  12  

所以行ID = 3会得到因为扔有将无法在同一分钟()和最大() BOTH列中的同一列。然后,您可以将其复制到新表格中。只有一次通过表...

2

第三个答案是现在的问题是稍微更清晰:

SELECT id, min(a) as a, min(b) as b 
FROM (SELECT DISTINCT id, a, b FROM table) t 
GROUP BY id 
HAVING count(*) =1 
0

您可以重建数据库,如果没有建立从原来的一个新的,用id作为主键? SQL可以处理其余的事情。