2009-08-17 40 views

Trả lời

26

Xem câu hỏi sau: Deleting duplicate rows from a table.

Các chuyển thể trả lời chấp nhận từ đó (đó là câu trả lời của tôi, vì vậy không "đánh cắp" ở đây ...):

Bạn có thể làm điều đó một cách đơn giản giả sử bạn có một trường ID duy nhất: bạn có thể xóa tất cả các bản ghi giống nhau, trừ ID, nhưng không có "ID tối thiểu" cho tên của chúng.

Ví dụ truy vấn:

DELETE FROM members 
WHERE ID NOT IN 
(
    SELECT MIN(ID) 
    FROM members 
    GROUP BY name 
) 

Trong trường hợp bạn không có một chỉ số duy nhất, đề nghị của tôi là chỉ cần thêm một chỉ số duy nhất tự động gia tăng. Chủ yếu là vì nó là thiết kế tốt, nhưng cũng bởi vì nó sẽ cho phép bạn chạy truy vấn ở trên.

+1

Dưới đây là cách tôi hiểu ở trên: Đối với mỗi tên, nó nhóm chúng (chỉ một nếu có duy nhất; một số thành một nếu trùng lặp), chọn ID nhỏ nhất từ ​​tập hợp và sau đó xóa bất kỳ hàng nào có ID không tồn tại trong bảng . Brilliant :) Cảm ơn nhiều Rax. – Gulbahar

+0

Bạn nhận được chính xác :) –

+1

trong mysql Tôi nhận được lỗi sau khi gửi truy vấn này: '" lỗi 1093 (HY000) nhưng nó đưa ra lỗi 'Bạn không thể chỉ định bảng mục tiêu' thành viên 'để cập nhật trong mệnh đề FROM "' ? –

4

Có lẽ sẽ dễ dàng hơn khi chọn những thứ duy nhất vào bảng mới, thả bảng cũ, sau đó đổi tên bảng tạm thời để thay thế bảng đó.

#create a table with same schema as members 
CREATE TABLE tmp (...); 

#insert the unique records 
INSERT INTO tmp SELECT * FROM members GROUP BY name; 

#swap it in 
RENAME TABLE members TO members_old, tmp TO members; 

#drop the old one 
DROP TABLE members_old; 
+0

Cảm ơn Paul. Đối với những người quan tâm ... TẠO TEMP TABLE tmp_members (tên VARCHAR); INSERT INTO tmp_members CHỌN tên TÊN thành viên GROUP BY name; CHỌN COUNT (tên) TỪ tmp_members; XÓA TỪ thành viên; các thành viên VACUUM; CHỌN COUNT (tên) TỪ thành viên; INSERT INTO thành viên (tên) SELECT * FROM tmp_members; CHỌN COUNT (tên) TỪ thành viên; CHỌN DISTINCT COUNT (tên) TỪ thành viên; SELECT tên FROM thành viên LIMIT 10; DROP TABLE tmp_members; – Gulbahar

+0

Xin lỗi, tôi đã bỏ lỡ rằng bạn đang sử dụng SQLite! –

0

Chúng tôi có một cơ sở dữ liệu khổng lồ, nơi xóa các bản sao là một phần của quy trình bảo trì thường xuyên. Chúng tôi sử dụng DISTINCT để chọn các bản ghi duy nhất sau đó ghi chúng vào một BẢNG TEMPORARY. Sau TRUNCATE chúng ta ghi lại dữ liệu TEMPORARY vào TABLE.

Đó là một cách để thực hiện và hoạt động như THỦ TỤC LƯU TRỮ.

+1

Tôi phải thừa nhận câu trả lời của Rax Olgud là phức tạp hơn nhiều và có thể chạy nhanh gấp 100 lần! :) - Tôi đang suy nghĩ về việc áp dụng giải pháp ... xứng đáng +1! –

0

Nếu chúng tôi muốn xem trước các hàng bạn sắp xóa. Sau đó xóa chúng.

with MYCTE as (
    SELECT DuplicateKey1 
     ,DuplicateKey2 --optional 
     ,count(*) X 
    FROM MyTable 
    group by DuplicateKey1, DuplicateKey2 
    having count(*) > 1 
) 
SELECT E.* 
FROM MyTable E 
JOIN MYCTE cte 
ON E.DuplicateKey1=cte.DuplicateKey1 
    AND E.DuplicateKey2=cte.DuplicateKey2 
ORDER BY E.DuplicateKey1, E.DuplicateKey2, CreatedAt 

Full dụ tại http://developer.azurewebsites.net/2014/09/better-sql-group-by-find-duplicate-data/

0

xóa hàng dup giữ một bảng có hàng trùng lặp và có thể một số hàng không có hàng trùng lặp sau đó nó giữ một hàng nếu có trùng lặp hoặc duy nhất trong một bảng. bảng có hai cột id và tên nếu chúng ta phải loại bỏ tên trùng lặp từ bảng và giữ một. Công việc của nó Fine ở cuối của tôi Bạn phải sử dụng truy vấn này.

DELETE FROM tablename 
WHERE id NOT IN(

SELECT id FROM 
(
    SELECT MIN(id)AS id 
    FROM tablename 
    GROUP BY name HAVING 
    COUNT(*) > 1 
)AS a) 
AND id NOT IN(
(SELECT ids FROM 
(
SELECT MIN(id)AS ids 
    FROM tablename 
    GROUP BY name HAVING 
    COUNT(*) =1 
)AS a1 
) 
) 

trước bảng xóa dưới nhìn thấy ảnh chụp màn hình: enter image description here sau bảng xóa được dưới đây xem các ảnh chụp màn hình truy vấn này xóa amit và Akhil hàng trùng lặp và giữ một bản ghi (amit và Akhil):

enter image description here

0

Bạn có thể tham gia bảng với chính mình bằng cách lĩnh vực phù hợp và xóa hàng unmatching

DELETE t1 FROM table_name t1 
LEFT JOIN tablename t2 ON t1.match_field = t2.match_field 
WHERE t1.id <> t2.id; 
Các vấn đề liên quan