2011-03-28 76 views
2

我如何找到多列的重复记录?表有主键(自动增量)找到多列重复mysql

EG

ID a_id b_id 
---- ---- ------ 
    1 34 23 
    2 34 23 
    3 35 25 

例如我想找到同样的A_ID和B_ID记录...

感谢

回答

3
select t.ID, t.a_id, t.b_id 
from (
    select a_id, b_id 
    from tbl 
    group by a_id, b_id 
    having count(*) > 1) x, tbl t 
where x.a_id = t.a_id and x.b_id = t.b_id 
order by t.a_id, t.b_id 

此查询将显示您的元组的所有副本(A_ID,B_ID)

+0

工作很好! – 2011-03-28 12:11:25

+0

也适合我。你如何确切地留下一个,所以在RULE101的例子中,当使用DELETE时,他的表将是ID#2和ID#3? – 2013-06-22 02:12:46

-1

这是一个基本的SQL查询:

SELECT * 
FROM my_table 
WHERE a_id = b_id; 

其中my_table是您的表的名称。

0

编辑:

误读是你所期待的。如上所述,您可以使用group by by参数来查找表中的重复条目,甚至可以使用自连接。

mysql> SELECT * FROM my_table; 
+------+------+------+ 
| ID | a_id | b_id | 
+------+------+------+ 
| 1 | 34 | 23 | 
| 2 | 34 | 23 | 
| 3 | 35 | 25 | 
+------+------+------+ 
3 rows in set (0.00 sec) 

mysql> SELECT t1.ID source_row, 
    ->  t2.ID same_as_row, 
    ->  t1.a_id a_id, 
    ->  t1.b_id b_id 
    -> FROM my_table t1 
    -> JOIN my_table t2 
    ->  ON t1.a_id = t2.a_id 
    -> AND t1.b_id = t2.b_id 
    -> AND t1.ID != t2.ID; 

+------------+-------------+------+------+ 
| source_row | same_as_row | a_id | b_id | 
+------------+-------------+------+------+ 
|   2 |   1 | 34 | 23 | 
|   1 |   2 | 34 | 23 | 
+------------+-------------+------+------+ 
2 rows in set (0.00 sec) 

EDIT2:

mysql> SELECT * FROM my_table; 
+------+------+------+ 
| ID | a_id | b_id | 
+------+------+------+ 
| 1 | 34 | 23 | # same as 2, 4 
| 2 | 34 | 23 | # same as 1, 4 
| 3 | 35 | 25 | 
| 4 | 34 | 23 | # same as 1, 2 
| 5 | 31 | 23 | 
+------+------+------+ 

mysql> SELECT t1.ID source_row, 
    ->   t2.ID same_as_row, 
    ->   t1.a_id a_id, 
    ->   t1.b_id b_id 
    ->  FROM my_table t1 
    ->  JOIN my_table t2 
    ->  ON t1.a_id = t2.a_id 
    ->  AND t1.b_id = t2.b_id 
    ->  AND t1.ID != t2.ID 
    -> ORDER BY source_row; 
+------------+-------------+------+------+ 
| source_row | same_as_row | a_id | b_id | 
+------------+-------------+------+------+ 
|   1 |   2 | 34 | 23 | 
|   1 |   4 | 34 | 23 | 
|   2 |   1 | 34 | 23 | 
|   2 |   4 | 34 | 23 | 
|   4 |   1 | 34 | 23 | 
|   4 |   2 | 34 | 23 | 
+------------+-------------+------+------+ 
6 rows in set (0.00 sec) 
+1

当您使用't1.ID != t2.ID',你将得到2个结果,对于相同的冲突(这在你的例子中很清楚),为了防止这种情况发生,你应该使用't1.ID t2.ID'当然是:p)。 – wimvds 2011-03-28 10:50:57

+0

我离开它,所以你可以看到两个并选择你想要删除的行。没有规定应该选择第一个,中间和最后一个副本。然而,当你有两个以上的副本时,这会变得很奇怪。它将在每次重复之后多次启动列出源行。请参阅编辑。 – DTing 2011-03-28 11:33:18

+0

是啊我有28个结果,即使有8个重复行 – 2011-03-28 12:08:42

1
SELECT r1.id, r2.id 
FROM test r1, test r2 
WHERE r1.id < r2.id 
AND r1.a_id = r2.a_id 
AND r1.b_id = r2.b_id 
+0

+1好的和简单的,老派的自我加入,r1.id r2.id)将确保每个冲突行只有一个命中(如果你不要这样做,你会得到2行,你的结果集中相同的冲突行)。 – wimvds 2011-03-28 10:48:26

+0

我真的不明白这个 – 2011-03-28 10:52:14

+0

这是一个自连接,也许(如果你只知道连接语法),如果你按照如下方式重写它会更有意义:SELECT r1.id,r2.id,r1.a_id,r1.b_id FROM test r1 INNER JOIN test r2 ON r2.a_id = r1.a_id AND r2.b_id = r1.b_id WHERE r1.id wimvds 2011-03-28 10:55:58