2013-01-23 13 views
59

Chúng tôi có một bảng hình ảnh với các cột sau:Tìm hàng trùng lặp với PostgreSQL

id, merchant_id, url 

bảng này chứa các giá trị trùng lặp cho sự kết hợp merchant_id, url. vì vậy có thể một hàng xuất hiện nhiều lần hơn.

234 some_merchant http://www.some-image-url.com/abscde1213 
235 some_merchant http://www.some-image-url.com/abscde1213 
236 some_merchant http://www.some-image-url.com/abscde1213 

Cách tốt nhất để xóa những trùng lặp đó là gì? (Tôi sử dụng PostgreSQL 9.2 và Rails 3.)

+1

Cột ID của bạn có độc đáo không? Tôi thấy 234 3 lần nhưng bạn nói merchant_id và url của bạn là các giá trị trùng lặp. – sgeddes

+0

Bản sao có thể có của http://stackoverflow.com/questions/1746213/how-to-delete-duplicate-entries-in-postgresql –

+0

xin lỗi vì sự nhầm lẫn. id trong ví dụ trên phải là duy nhất. cảm ơn cho chỉnh sửa chính xác. giải pháp ở đây stackoverflow.com/questions/1746213/… không hoạt động đối với trường hợp của tôi. –

Trả lời

105

Đây là sự lựa chọn của tôi.

select * from (
    SELECT id, 
    ROW_NUMBER() OVER(PARTITION BY merchant_Id, url ORDER BY id asc) AS Row 
    FROM Photos 
) dups 
where 
dups.Row > 1 

Vui lòng phát theo thứ tự để điều chỉnh các bản ghi mà bạn muốn xóa theo đặc điểm kỹ thuật của mình.

SQL Fiddle =>http://sqlfiddle.com/#!15/d6941/1/0


SQL Fiddle cho Postgres 9.2 không còn được hỗ trợ; cập nhật SQL Fiddle lên postgres 9.3

+2

Điều này làm việc như một sự quyến rũ nhưng làm thế nào để bạn xóa các bản sao được tìm thấy bằng truy vấn này? –

+1

Hãy cẩn thận http://sqlfiddle.com/#!12/796d6/133 – MatthewJ

+0

Nếu chúng ta có cùng một điều lặp đi lặp lại 3 lần, mất 2 và lấy 3 được thực hiện trong kết quả. Làm thế nào tôi có thể giải quyết nó? –

6

Tôi thấy một vài tùy chọn cho bạn.

Đối với một cách nhanh chóng để làm việc đó, sử dụng một cái gì đó như thế này (nó giả định cột ID của bạn không phải là độc đáo như bạn đề cập đến 234 nhiều lần trên):

CREATE TABLE tmpPhotos AS SELECT DISTINCT * FROM Photos; 
DROP TABLE Photos; 
ALTER TABLE tmpPhotos RENAME TO Photos; 

Đây là SQL Fiddle.

Bạn sẽ cần phải thêm các ràng buộc của mình trở lại bảng nếu có.

Nếu cột ID của bạn là duy nhất, bạn có thể làm một cái gì đó như để giữ id thấp nhất của bạn:

DELETE FROM P1 
USING Photos P1, Photos P2 
WHERE P1.id > P2.id 
    AND P1.merchant_id = P2.merchant_id 
    AND P1.url = P2.url; 

Fiddle.

+2

id là duy nhất trong trường hợp của tôi. Tôi đã làm điều đó sai trong mã ví dụ của tôi. nhưng tôi gặp lỗi nếu tôi cố gắng sử dụng giải pháp thứ hai của bạn. 'ERROR: mối quan hệ" p1 "không tồn tại ' –

+0

@StefanSchmidt Tôi đã sửa nó để chạy trên Postgres thay vì MySQL: http://sqlfiddle.com/#!12/6b1a7/1 – 11101101b

8

Phần thứ hai của câu trả lời của sgeddes không hoạt động trên Postgres (fiddle sử dụng MySQL). Đây là phiên bản cập nhật câu trả lời của anh ấy bằng cách sử dụng Postgres: http://sqlfiddle.com/#!12/6b1a7/1

DELETE FROM Photos AS P1 
USING Photos AS P2 
WHERE P1.id > P2.id 
    AND P1.merchant_id = P2.merchant_id 
    AND P1.url = P2.url;