2013-01-31 80 views
5

thể trùng lặp:
How to delete duplicate rows with SQL?Làm thế nào để xóa các bản ghi trùng lặp trong sql

Tôi có một bảng với hồ sơ và tôi muốn xóa tất cả các bản ghi trùng lặp

DELETE FROM 'table' 
WHERE 'field' IN 
(
SELECT 'field' FROM 'table' GROUP BY 'field' 
HAVING (COUNT('field')>1) 
) 

Tại sao điều này có hiệu quả không?

+0

Bạn có nhận được thông báo lỗi hoặc truy vấn chạy thành công không? –

+1

willnt truy vấn của bạn xóa tất cả các lĩnh vực bao gồm cả bản sao? nếu bạn có 2 bản sao với ID đó, truy vấn IN() của bạn sẽ xóa cả hai. Bạn không muốn giữ ít nhất một bản ghi? – GGio

+2

mysql không cho phép bạn cập nhật/xóa trên bảng mà từ đó bạn đang chọn dữ liệu. –

Trả lời

5

Có thể bạn có thể khám phá bằng lệnh DISTINCT để chỉ chọn các bản ghi duy nhất dựa trên một trường.

Bạn có thể tạo bảng mới với các mục nhập duy nhất dựa trên. Ví dụ:

CREATE TABLE nonDuplicates 
SELECT DISTINCT * FROM yourTable group by field 
+1

Điều này sẽ chỉ hoạt động vì xử lý của MySQL GROUP BY về cơ bản là không chính xác và cho phép cú pháp không hợp lệ này. Nhưng nó có lẽ là giải pháp nhanh nhất. –

+0

Cảm ơn Peixe nó đã hoạt động tốt! – vdhmartijn

+1

@vdhmartijn: vui lòng đọc http://rpbouman.blogspot.de/2007/05/debunking-group-by-myths.html này để hiểu * tại sao * nó hoạt động trong MySQL và tại sao các DBMS khác sẽ từ chối câu lệnh không hợp lệ. –

1

này mang đến cho bạn nhiều hơn một kết quả: -

SELECT field FROM `table` 
GROUP BY field 
HAVING (COUNT('field)>1 

Cố gắng chenge này bằng cách:

SELECT TOP 1 field 
FROM `table` 
GROUP BY field 
HAVING (COUNT(field)>1 
+0

CHỌN TOP 1 không hoạt động cho tôi .. vẫn không hoạt động – vdhmartijn

+0

Làm cách nào để xóa nội dung này? –

0

đầu tiên nhận được tất cả các bản sao và lưu trữ chúng trong mảng.

SELECT field 
FROM `table` 
GROUP BY field 
HAVING COUNT('field') > 1 

bây giờ làm php bạn để tiết kiệm một kết quả nào bạn muốn và sau đó thực hiện

DELETE 
FROM `table` 
WHERE field IN (your values) AND field != savedID 
+0

Cảm ơn bạn đã phản ứng, nhưng ý định của tôi là làm việc mà không cần PHP chỉ SQL – vdhmartijn

0

MySQL có một hạn chế rất đáng ghét mà không thể sử dụng bảng đang được cập nhật/xóa/chèn vào trong một tiểu -lựa chọn.

Nhưng bạn có thể giải quyết vấn đề này bằng cách tham gia bảng để xóa (thay vì sử dụng lựa chọn phụ).

Giả sử bạn có một số loại định danh duy nhất trong bảng của bạn (tôi giả sử một cột id trong tuyên bố sau):

DELETE d 
FROM table_with_duplicates d 
JOIN ( 
    SELECT min(id) as min_id, field 
    FROM table_with_duplicates 
    GROUP BY field 
) keep ON keep.field = d.field 
     AND keep.min_id <> d.id; 

Điều này sẽ giữ một hàng cho mỗi người trong số các bản sao (một với Lowes giá trị trong cột id).

Nếu bạn muốn xóa tất cả hàng trùng lặp (không lưu giữ ít nhất một), chỉ cần xóa điều kiện AND keep.min_id <> d.id.

Sửa

Nếu bạn không có một cột duy nhất, nhưng muốn loại bỏ tất cả bản sao (không giữ ít nhất một dòng), sau đó bạn có thể sử dụng:

DELETE d 
FROM table_with_duplicates d 
JOIN ( 
    SELECT field 
    FROM table_with_duplicates 
    GROUP BY field 
    HAVING count(*) > 1 
) del ON del.field = d.field; 
+0

Và nếu tôi không có ID thì vẫn còn cách để giải quyết vấn đề này? – vdhmartijn

+0

@vdhmartijn: Nếu bạn muốn xóa ** tất cả ** bản sao (không lưu giữ ít nhất một), thì bạn có thể làm mà không có ID. Nếu không, hãy xem câu trả lời của Peixe. –

+0

cảm ơn vì đã giúp nó hoạt động ngay bây giờ! – vdhmartijn

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