2008-10-13 9 views
41

Ví dụ về một SQL nhanh để lấy các bản sao trong tập dữ liệu với hàng trăm nghìn bản ghi là gì. Tôi thường sử dụng một cái gì đó như:Kịch bản lệnh "Sao chép nhanh nhất" nhanh nhất

SELECT afield1, afield2 FROM afile a 
WHERE 1 < (SELECT count(afield1) FROM afile b WHERE a.afield1 = b.afield1); 

Nhưng điều này khá chậm.

Trả lời

74

Đây là cách trực tiếp hơn:

select afield1,count(afield1) from atable 
group by afield1 having count(afield1) > 1 
15

Bạn có thể thử:

select afield1, afield2 from afile a 
where afield1 in 
(select afield1 
    from afile 
    group by afield1 
    having count(*) > 1 
); 
+2

Đây thực sự là cách ưa thích của tôi vì bạn có thể trả về tất cả các cột của bảng. – leek

+0

Thật kỳ lạ, 2 người đã bỏ phiếu cho câu trả lời này mà không bình luận về lý do. Tôi đoán điều này có nghĩa là có cái gì đó sai trái với nó? –

+0

Tôi đoán nó chậm hơn –

5

Một câu hỏi tương tự đã được hỏi tuần trước. Có một số câu trả lời hay ở đó.

SQL to find duplicate entries (within a group)

Trong câu hỏi đó, OP đã quan tâm đến tất cả các cột (trường) trong bảng (file), nhưng hàng thuộc trong cùng một nhóm nếu họ có giá trị quan trọng như nhau (afield1).

Có ba loại câu trả lời:

truy vấn con trong mệnh đề where, giống như một số câu trả lời khác tại đây.

một bên tham gia giữa các bảng và các nhóm được xem như là một bảng (câu trả lời của tôi)

và truy vấn phân tích (một cái gì đó mới mẻ với tôi).

5

Bằng cách này, nếu có ai muốn loại bỏ các bản sao, tôi đã sử dụng này:

delete from MyTable where MyTableID in (
    select max(MyTableID) 
    from MyTable 
    group by Thing1, Thing2, Thing3 
    having count(*) > 1 
) 
+0

Chỉ cần nhận thấy rằng điều này sẽ chỉ xóa một trong các bản sao. Nếu có ba hàng có cùng giá trị, bạn phải chạy truy vấn này hai lần để loại bỏ tất cả các bản sao. –

3

này nên được hợp lý nhanh (thậm chí nhanh hơn nếu dupeFields được lập chỉ mục).

SELECT DISTINCT a.id, a.dupeField1, a.dupeField2 
FROM TableX a 
JOIN TableX b 
ON a.dupeField1 = b.dupeField2 
AND a.dupeField2 = b.dupeField2 
AND a.id != b.id 

Tôi đoán nhược điểm duy nhất để truy vấn này là vì bạn không làm một COUNT(*) bạn không thể kiểm tra số lượng lần nó được nhân đôi, duy nhất mà nó xuất hiện nhiều hơn một lần.

+0

Điều này không thực sự nhanh khi tôi thử trên bàn của tôi. Tôi không có một chỉ số mặc dù. –