2013-04-07 55 views
7

Tôi có một bảng:Cách hiệu quả nhất để xóa tất cả các hàng trùng lặp khỏi bảng?

| foo | bar | 
+-----+-----+ 
| a | abc | 
| b | def | 
| c | ghi | 
| d | jkl | 
| a | mno | 
| e | pqr | 
| c | stu | 
| f | vwx | 

Tôi muốn xóa tất cả hàng chứa bản sao bằng foo cột để các bảng sẽ trông như thế này:

| foo | bar | 
+-----+-----+ 
| b | def | 
| d | jkl | 
| e | pqr | 
| f | vwx | 

các hiệu quả nhất là gì cách để làm điều này?

Trả lời

9

Bạn có thể tham gia bảng từ truy vấn con chỉ trả về duy nhất foo sử dụng LEFT JOIN. Các hàng mà không có một trận đấu trên subquery sẽ bị xóa khi bạn mong muốn, ví dụ

DELETE a 
FROM TableName a 
     LEFT JOIN 
     (
      SELECT foo 
      FROM TableName 
      GROUP BY Foo 
      HAVING COUNT(*) = 1 
     ) b ON a.Foo = b.Foo 
WHERE b.Foo IS NULL 

Đối với hiệu suất nhanh hơn, thêm một chỉ mục trên cột Foo.

ALTER TABLE tableName ADD INDEX(foo) 
+0

này hoạt động hoàn hảo nhưng nó quá chậm (Tôi có một bảng rất lớn). –

+0

thêm chỉ mục trên cột để nó sẽ hoạt động nhanh hơn, ví dụ, 'ALTER TABLE tableName ADD INDEX (foo)' và xem hiệu suất. –

+0

Cảm ơn nhưng tôi đã làm điều đó. Nhưng đó là cách nhanh nhất để làm điều này, dù sao, tôi hiểu. –

8

Sử dụng EXISTS:

DELETE a 
    FROM TableName a 
WHERE EXISTS (SELECT NULL 
       FROM TableName b 
       WHERE b.foo = a.foo 
      GROUP BY b.foo 
       HAVING COUNT(*) > 1) 

Sử dụng IN:

DELETE a 
    FROM TableName a 
WHERE a.foo IN (SELECT b.foo 
        FROM TableName b 
       GROUP BY b.foo 
       HAVING COUNT(*) > 1) 
+0

Nếu tôi sửa phiên bản hiện tại bạn đã viết ở đây thì nhanh hơn đáng kể so với phiên bản trong phiên bản. Với điều này trong tâm trí, là có bất kỳ đối số cho phiên bản trong? – usumoio

Các vấn đề liên quan