Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

6 cách để xóa các dòng trùng lặp có khóa chính trong Oracle

Dưới đây là một số tùy chọn để xóa các hàng trùng lặp khỏi bảng trong Cơ sở dữ liệu Oracle khi các hàng đó có khóa chính hoặc cột định danh duy nhất.

Trong những trường hợp như vậy, khóa chính phải được bỏ qua khi so sánh các hàng trùng lặp (do thực tế là khóa chính giữ các giá trị duy nhất).

Dữ liệu Mẫu

Các ví dụ của chúng tôi sử dụng dữ liệu sau:

SELECT * FROM Dogs;

Kết quả:

DOGID FIRSTNAME LASTNAME
1 Vỏ cây Smith
2 Vỏ cây Smith
3 Gâu Jones
4 Ruff Robinson
5 Wag Johnson
6 Wag Johnson
7 Wag Johnson

Chúng ta có thể thấy rằng hai hàng đầu tiên là trùng lặp, ba hàng cuối cùng cũng vậy.

DogId cột chứa các giá trị duy nhất (vì đó là khóa chính của bảng), nhưng chúng tôi đang bỏ qua cột đó khi so sánh các bản sao. Bạn có thể thường thấy mình cần loại bỏ các bảng có chứa khóa chính và vì vậy, các ví dụ sau đây có thể được sử dụng để làm điều đó.

Tùy chọn 1

Đây là tùy chọn đầu tiên của chúng tôi để loại bỏ lừa đảo trong bảng trên:

DELETE FROM Dogs 
WHERE DogId IN (
    SELECT DogId FROM Dogs 
    MINUS SELECT MIN(DogId) FROM Dogs 
    GROUP BY FirstName, LastName
    );

SELECT * FROM Dogs;

Kết quả:

DOGID FIRSTNAME LASTNAME
1 Vỏ cây Smith
3 Gâu Jones
4 Ruff Robinson
5 Wag Johnson

Các bản sao đã bị xóa (nhưng một hàng của mỗi bản sao vẫn còn).

Ngoài ra, chúng ta có thể sử dụng MAX () thay vì MIN () chức năng thay đổi các hàng bị xóa.

Tùy chọn 2

Trong ví dụ này (và các ví dụ sau), chúng tôi sẽ giả định rằng bảng đã được khôi phục về trạng thái ban đầu (với các bản sao).

Đây là một ví dụ khác giúp loại bỏ bảng và sau đó chọn các hàng còn lại:

DELETE FROM Dogs WHERE DogId IN (
    SELECT d2.DogId 
    FROM Dogs d1, Dogs d2 
    WHERE d1.FirstName = d2.FirstName 
    AND d1.LastName = d2.LastName 
    AND d1.DogId <> d2.DogId 
    AND d1.DogId=( 
        SELECT MAX(DogId) 
        FROM Dogs d3 
        WHERE d3.FirstName = d1.FirstName 
        AND d3.LastName = d1.LastName
    )
);

SELECT * FROM Dogs;

Kết quả:

DOGID FIRSTNAME LASTNAME
2 Vỏ cây Smith
3 Gâu Jones
4 Ruff Robinson
7 Wag Johnson

Lưu ý rằng tôi đã sử dụng MAX () hàm thay vì MIN () mà tôi đã sử dụng trong ví dụ trước. Chúng ta có thể thấy ảnh hưởng của điều này đối với hoạt động khử lừa đảo. Nó đã xóa các hàng khác nhau khỏi bảng.

Tùy chọn 3

Đây là một tùy chọn không yêu cầu sử dụng MIN () hoặc MAX () :

DELETE FROM Dogs
WHERE EXISTS (
  SELECT 1 FROM Dogs d2 
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
  AND Dogs.DogId > d2.DogId
);

SELECT * FROM Dogs;

Kết quả:

DOGID FIRSTNAME LASTNAME
1 Vỏ cây Smith
3 Gâu Jones
4 Ruff Robinson
5 Wag Johnson

Tùy chọn 4

Đây là một tùy chọn khác:

DELETE FROM Dogs
WHERE DogId > (
  SELECT MIN(DogId) FROM Dogs d2  
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
);

SELECT * FROM Dogs;

Kết quả:

DOGID FIRSTNAME LASTNAME
1 Vỏ cây Smith
3 Gâu Jones
4 Ruff Robinson
5 Wag Johnson

Tùy chọn 5

Mỗi hàng trong Oracle có một rowid cột giả trả về địa chỉ của hàng. rowid là mã định danh duy nhất cho các hàng trong bảng và thường giá trị của nó xác định duy nhất một hàng trong cơ sở dữ liệu (mặc dù điều quan trọng cần lưu ý là các hàng trong các bảng khác nhau được lưu trữ cùng nhau trong cùng một cụm có thể có cùng một rowid ).

Do đó, chúng tôi có thể sử dụng rowid trong truy vấn của chúng tôi thay vì DogId cột:

DELETE FROM Dogs
WHERE EXISTS (
  SELECT 1 FROM Dogs d2 
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
  AND Dogs.rowid > d2.rowid
);

SELECT * FROM Dogs;

Kết quả:

DOGID FIRSTNAME LASTNAME
1 Vỏ cây Smith
3 Gâu Jones
4 Ruff Robinson
5 Wag Johnson

Mặc dù ví dụ này có vẻ hơi thừa, vì chúng ta đã có cột khóa chính, có thể có những trường hợp bạn thích sử dụng rowid . rowid có thể hữu ích nếu bạn không thể sử dụng cột khóa chính vì lý do nào đó hoặc nếu bảng không có khóa chính. Ngoài ra, tài liệu của Oracle đề cập rằng rowid giá trị là cách nhanh nhất để truy cập vào một hàng.

Tùy chọn 6

Và đây là ví dụ khác, nhưng với rowid thay vì khóa chính:

DELETE FROM Dogs
WHERE rowid > (
  SELECT MIN(rowid) FROM Dogs d2  
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
);

SELECT * FROM Dogs;

Kết quả:

DOGID FIRSTNAME LASTNAME
1 Vỏ cây Smith
3 Gâu Jones
4 Ruff Robinson
5 Wag Johnson

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ORA-00903:tên bảng không hợp lệ trên PreparedStatement

  2. ORA-00933:Lệnh SQL không được kết thúc đúng cách

  3. Cách trả về danh sách các múi giờ hợp lệ trong cơ sở dữ liệu Oracle

  4. Addnode Resolutionv.conf Failures

  5. Sao lưu trực tuyến Vs ngoại tuyến