2012-01-03 27 views
8

Tôi đã có một bảng với 6 cột:xem tất cả dữ liệu cho các hàng trùng lặp trong oracle

  • id
  • name
  • type_id
  • code
  • lat
  • long

Ba yêu cầu đầu tiên là bắt buộc. ID là khóa riêng tư, được chèn tự động với một chuỗi.

Tôi có một số hàng trùng lặp, như được xác định bởi CẢ HAI nametype_id là bằng nhau, nhưng tôi muốn xem tất cả dữ liệu cho các bản sao. Tôi có thể tìm thấy các bản duply đơn giản là đủ:

SELECT name 
     , type_id 
FROM table1 
GROUP BY name 
     , type_id 
HAVING COUNT(*) > 1 

nhưng thực sự xem tất cả thông tin là làm tôi bối rối. Tôi biết điều này nên đơn giản, nhưng tôi đang đánh một bức tường ở đây.

Trả lời

15

Bạn luôn có thể sử dụng truy vấn GROUP BY/HAVING trong mệnh đề IN. Điều này hoạt động và tương đối đơn giản nhưng nó có thể không đặc biệt hiệu quả nếu số hàng trùng lặp là tương đối lớn.

SELECT * 
    FROM table1 
WHERE (name, type_id) IN (SELECT name, type_id 
          FROM table1 
          GROUP BY name, type_id 
          HAVING COUNT(*) > 1) 

Nói chung sẽ hiệu quả hơn khi sử dụng các chức năng phân tích để tránh đánh bảng lần thứ hai.

SELECT * 
    FROM (SELECT id, 
       name, 
       type_id, 
       code, 
       lat, 
       long, 
       count(*) over (partition by name, type_id) cnt 
      FROM table1) 
WHERE cnt > 1 

Tùy thuộc vào những gì bạn đang có kế hoạch để làm với các dữ liệu và có bao nhiêu bản sao của một hàng cụ thể có thể có, bạn cũng có thể muốn tham gia table1 để bản thân để có được các dữ liệu trong một hàng duy nhất

SELECT a.name, 
     a.type_id, 
     a.id, 
     b.id, 
     a.code, 
     b.code, 
     a.lat, 
     b.lat, 
     a.long, 
     b.long 
    FROM table1 a 
     JOIN table1 b ON (a.name = b.name AND 
         a.type_id = b.type_id AND 
         a.rowid > b.rowid) 
+0

Suy nghĩ đầu tiên của tôi là truy vấn đầu tiên, nhưng tôi không biết liệu bạn có thể sử dụng hai cột trong mệnh đề IN hay không. Tôi đoán tôi nên thử. Cám ơn. – Marc

1
SELECT * 
FROM table1 t1 
WHERE (t1.name,t1.type_id) in (SELECT DISTINCT name 
               , type_id 
           FROM  table1 
           GROUP BY name, type_id 
           HAVING COUNT(*) > 1) 

Làm điều đó.

HTH

1

Bạn có thể làm một tự tham gia vào bảng để tìm tất cả các cặp trùng lặp:

SELECT 
    a.name name 
, a.type_id type_id_a 
, a.code code_a 
, a.lat  lat_a 
, a.long long_a 
, b.code code_b 
, b.lat  lat_b 
, b.long long_b 
FROM table1 a 
JOIN table1 b 
ON a.name = b.name 
AND a.type_id = b.type_id 
AND a.ROWID > b.ROWID 

Để chắc chắn rằng một hàng không phù hợp với bản thân và mỗi cặp là chỉ ra một lần, Tôi đã thêm a.ROWID > b.ROWID, hoạt động cho Oracle. Bạn sẽ cần một cách khác để tách chúng ra nếu bạn sử dụng một cơ sở dữ liệu khác.

+0

Có lẽ, bạn muốn có điều kiện nối bổ sung để đảm bảo rằng hàng được trả về từ 'A' và từ' B' thực sự là các hàng khác nhau. Một cái gì đó như 'AND a.id> b.id' hoặc' AND a.rowid> b.rowid' –

+0

Cảm ơn, tôi đã cập nhật câu trả lời. –

0

Điều đó vẫn không tìm thấy đôi nếu một trong các trường so sánh có giá trị NULL. Để có được, tôi sử dụng nvl để relace NULL trong các trường so sánh với một giá trị mà tôi biết không thể xảy ra trong bảng/lĩnh vực đó.

-2

Chỉ cần đặt NULLS 0 ...

... sử dụng chức năng NVL.

Các vấn đề liên quan