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

6 cách chọn hàng trùng lặp trong Oracle

Các ví dụ sau trả về các hàng trùng lặp từ bảng Cơ sở dữ liệu Oracle.

Dữ liệu Mẫu

Giả sử chúng ta có một bảng với dữ liệu sau:

SELECT * FROM Pets;

Kết quả:

PetId  PetName  PetType
-----  -------  -------
1      Wag      Dog    
1      Wag      Dog    
2      Scratch  Cat    
3      Tweet    Bird   
4      Bark     Dog    
4      Bark     Dog    
4      Bark     Dog    

Hai hàng đầu tiên trùng lặp, ba hàng cuối cùng cũng vậy. Trong trường hợp này, các hàng trùng lặp chứa các giá trị trùng lặp trên tất cả các cột, bao gồm cả cột ID.

Tùy chọn 1

Chúng ta có thể sử dụng truy vấn sau để xem có bao nhiêu hàng trùng lặp:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
ORDER BY PetId;

Kết quả:

PETID	PETNAME	PETTYPE	Count
1	Wag	Dog	2
2	Scratch	Cat	1
3	Tweet	Bird	1
4	Bark	Dog	3

Chúng tôi đã nhóm các hàng theo tất cả các cột và trả về số hàng của mỗi nhóm. Bất kỳ hàng nào có số lượng lớn hơn 1 đều là hàng trùng lặp.

Chúng tôi có thể sắp xếp nó theo số lượng theo thứ tự giảm dần, để các hàng có nhiều bản sao nhất sẽ xuất hiện đầu tiên:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
ORDER BY Count(*) DESC;

Kết quả:

PETID	PETNAME	PETTYPE	Count
4	Bark	Dog	3
1	Wag	Dog	2
2	Scratch	Cat	1
3	Tweet	Bird	1

Tùy chọn 2

Nếu chúng ta chỉ muốn các hàng trùng lặp được liệt kê, chúng ta có thể sử dụng HAVING mệnh đề chỉ trả về các hàng có tổng số lớn hơn 1:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC;

Kết quả:

PETID	PETNAME	PETTYPE	Count
4	Bark	Dog	3
1	Wag	Dog	2

Tùy chọn 3

Một tùy chọn khác là sử dụng ROW_NUMBER() chức năng cửa sổ:

SELECT 
    PetId,
    PetName,
    PetType,
    ROW_NUMBER() OVER ( 
        PARTITION BY PetId, PetName, PetType 
        ORDER BY PetId, PetName, PetType
        ) AS rn
FROM Pets;

Kết quả:

PETID	PETNAME	PETTYPE	RN
1	Wag	Dog	1
1	Wag	Dog	2
2	Scratch	Cat	1
3	Tweet	Bird	1
4	Bark	Dog	1
4	Bark	Dog	2
4	Bark	Dog	3

PARTITION BY mệnh đề chia tập kết quả được tạo ra bởi FROM mệnh đề thành các phân vùng mà hàm được áp dụng. Khi chúng ta chỉ định phân vùng cho tập kết quả, mỗi phân vùng sẽ làm cho việc đánh số bắt đầu lại (tức là việc đánh số sẽ bắt đầu từ 1 cho hàng đầu tiên trong mỗi phân vùng).

Tùy chọn 4

Chúng ta có thể sử dụng truy vấn trên làm biểu thức bảng chung:

WITH cte AS 
    (
        SELECT 
            PetId,
            PetName,
            PetType,
            ROW_NUMBER() OVER ( 
                PARTITION BY PetId, PetName, PetType 
                ORDER BY PetId, PetName, PetType
                ) AS Row_Number
        FROM Pets
    )
SELECT * FROM cte WHERE Row_Number <> 1;

Kết quả:

PETID	PETNAME	PETTYPE	ROW_NUMBER
1	Wag	Dog	2
4	Bark	Dog	2
4	Bark	Dog	3

Điều này chỉ trả về các hàng thừa từ các bản sao phù hợp. Vì vậy, nếu có hai hàng giống nhau, nó trả về một trong số chúng. Nếu có ba hàng giống nhau, nó trả về hai, v.v.

Tùy chọn 5

Do bảng của chúng tôi không chứa cột khóa chính, chúng tôi có thể tận dụng rowid của Oracle cột giả:

SELECT * FROM Pets
WHERE EXISTS (
  SELECT 1 FROM Pets p2 
  WHERE Pets.PetName = p2.PetName
  AND Pets.PetType = p2.PetType
  AND Pets.rowid > p2.rowid
);

Kết quả:

PETID	PETNAME	PETTYPE
1	Wag	Dog
4	Bark	Dog
4	Bark	Dog

Cách hoạt động của điều này là, mỗi hàng trong cơ sở dữ liệu 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. Tuy nhiên, đ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 .

Một lợi ích của ví dụ trên là chúng ta có thể thay thế SELECT * với DELETE để xóa mờ bảng.

Tùy chọn 6

Và cuối cùng, đây là một tùy chọn khác sử dụng rowid cột giả:

SELECT * FROM Pets
WHERE rowid > (
  SELECT MIN(rowid) FROM Pets p2  
  WHERE Pets.PetName = p2.PetName
  AND Pets.PetType = p2.PetType
);

Kết quả:

PETID	PETNAME	PETTYPE
1	Wag	Dog
4	Bark	Dog
4	Bark	Dog

Kết quả tương tự như ví dụ trước.

Như với ví dụ trước, chúng ta có thể thay thế SELECT * với DELETE để xóa các hàng trùng lặp khỏi bảng.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. oracle EBS R12 là gì

  2. ORA-01658:không thể tạo phạm vi BAN ĐẦU cho phân đoạn trong vùng bảng TS_DATA

  3. Làm cách nào để thoát dấu phẩy và dấu ngoặc kép cùng một lúc cho tệp CSV?

  4. MySQL tương đương với xếp hạng ORACLES ()

  5. Làm cách nào để tăng bộ đệm dbms_output?