2013-08-29 67 views
6

Tôi đã tìm kiếm Find duplicate entries in a columnOracle: find duplicate rows in select query, nhưng dường như không thể nhận được bất kỳ câu trả lời ...Tìm mục trùng lặp trong một cột Oracle SQL

Tôi có một số dữ liệu mà trông như thế này

columnA columnB columnC 
1111111 emailID1 true 
1111111 emailID2 false 
1111222 emailID3 true 
1111339 emailID4 true 
2384398 emailID5 true 

Tôi muốn chỉ hiển thị các cột có cùng giá trị trong cộtA nhưng có thể khác nhau trong cộtB và/hoặc C:

columnA columnB columnC 
1111111 emailID1 true 
1111111 emailID2 false 

Sử dụng việc có> 1 dường như không thực sự captu tái này, bất kỳ ý tưởng? Cảm ơn.

+0

Nhân tiện, tôi chỉ tìm kiếm trên một bảng, không cần tham gia. :) –

+0

một số giải pháp được trình bày liên quan đến * tự tham gia *, do đó, phép nối * là * một giải pháp hợp lệ cho vấn đề của bạn. –

Trả lời

0
SELECT T.columnA, S.columnB, S.columnC FROM 
(
SELECT columnA FROM someTable 
GROUP BY columnA 
HAVING COUNT(*) > 1 
) T INNER JOIN someTable S ON T.columnA = S.columnA 
7

Sử dụng having count(*) > 1 chỉ bằng một nửa câu đố. Nửa còn lại nhận được các hàng tương ứng.

Bạn có thể làm điều đó như thế này:

SELECT * 
FROM MyTable 
WHERE ColumnA IN (
    SELECT ColumnA FROM MyTable GROUP BY ColumnA HAVING COUNT(*) > 1 
) 
+0

+1, nhưng bạn có thể làm điều đó với một tham gia để lựa chọn phụ của bạn quá, mà sẽ quy mô. – Bohemian

0

Bạn có thể làm điều này bằng chức năng phân tích. Tìm min và max và trả lại hàng mà họ đang có khác nhau:

select columnA, columnB, columnC 
from (select t.*, min(t.columnC) over (partition by columnA, columnB) as minC, 
      max(t.columnC) over (partition by columnA, columnB) as maxC 
     from t 
    ) t 
where minC <> maxC; 
5

Hãy thử điều này:

SELECT t.* 
FROM (SELECT ColumnA FROM MyTable GROUP BY ColumnA HAVING COUNT(*) > 1) dups 
JOIN MyTable t ON t.ColumnA = dups.ColumnA 

này sẽ mở rộng quy mô cũng quá, miễn là một chỉ số là trên ColumnA:

create index MyTable_ColumnA on MyTable(ColumnA); 

chỉ mục như vậy sẽ được sử dụng cho cả truy vấn chính và truy vấn bên trong, mang đến cho bạn hiệu suất rất tốt.

+1

+1 Mặc dù tôi thích giao diện của 'IN' tốt hơn một chút, nhưng 100% đồng ý rằng' JOIN' làm cho bạn ít phụ thuộc vào trình tối ưu hóa. – dasblinkenlight

+0

Thật không may là tôi không tham gia 2 bảng ... –

+1

Tất nhiên là không - trong trường hợp này, gợi ý là tham gia cùng một bảng. Truy vấn bên trong xác định các hàng trùng lặp, truy vấn bên ngoài thu thập các cột khác mà bạn muốn trong kết quả. –

1

Tôi thường muốn tránh chạm bàn nhiều hơn một lần trong truy vấn - điều này sẽ làm việc tốt ngay cả khi không một chỉ số - chỉ làm một lần quét qua bảng:

SELECT columnA, columnB, columnC 
FROM (SELECT mytable.* 
      ,COUNT(*) OVER (PARTITION BY columnA) countA 
     FROM mytable) 
WHERE countA > 1 
0

chủ đề này có thể là cũ nhưng nó là đáng để cập nhật tất cả mọi người giải pháp tốt hơn/hiệu quả hơn để tìm các bản ghi trùng lặp. Bạn có thể sử dụng phân vùng để tìm các bản ghi trùng lặp trên các cột phù hợp (nhiều cột như bạn cần mà không cần sử dụng tham gia bên trong).

SELECT * 
FROM (
     SELECT t.*, ROW_NUMBER() OVER (PARTITION BY column1, column2 ORDER BY your_key_column) AS duplicate_count 
     FROM yourtable t 
     ) 
WHERE duplicate_count > 1 --get duplicate records for the matching value in column1 and column2 

Xem câu trả lời gốc từ @Quassnoi theo số here. Cảm ơn anh ấy, một giải pháp rất thông minh bằng cách sử dụng phân vùng.

0

Nếu bạn đang tìm kiếm mục với id duy nhất trong cơ sở dữ liệu của bạn, nơi nhiều phím trong một cột có thể xảy ra, sau đó một cách đơn giản việc tìm kiếm chúng là tạo ra hai bảng như exlplained dưới đây:

đây: TICKETID là một chính , TKTNUMBER có thể xảy ra nhiều lần.

CREATE TABLE TEMP 
(
    TICKETID FLOAT, 
    TKTNUMBER FLOAT 
); 

CREATE TABLE TEMP2 
(
    TKTNUMBER FLOAT, 
    COUNTER  INTEGER 
); 

Đặt trong tất cả các của TICKETID và TKTNUMBER bằng cách chỉ nhìn vào TKTNUMBERS với COUNT (TKTNUMBER)> 1:

INSERT INTO TEMP 
    SELECT 
     TICKETID, 
     TKTNUMBER 
    FROM YOUR_TABLE 
    WHERE TKTNUMBER IN ( 
      SELECT TKTNUMBER 
      FROM YOUR_TABLE 
      HAVING COUNT (TKTNUMBER) > 1 
      GROUP BY TKTNUMBER); 

Cuối cùng, để xem quầy, đặt trong TKTNUMBER và COUNT cùng cách như trên:

INSERT INTO TEMP2 
    SELECT 
     TKTNUMBER, 
     COUNT (TKTNUMBER) AS COUNTER 
    FROM YOUR_TABLE 
    HAVING COUNT (TKTNUMBER) > 1 
    GROUP BY TKTNUMBER 
    ORDER BY 2 DESC 

Bạn có thể chọn như sau (bằng cách tham gia hai bảng trên tktnumber):

SELECT 
    T1.TICKETID, 
    T1.TKTNUMBER, 
    T2.COUNTER 
FROM 
    TEMP T1 INNER JOIN 
    TEMP2 T2 ON 
     T2.TKTNUMBER = T1.TKTNUMBER 
ORDER BY T2.COUNTER DESC 
Các vấn đề liên quan