2012-01-12 44 views
7

xem xét bảng sau:SQL: Loại bỏ hồ sơ trùng lặp - mặc dù loại khác nhau

TAB6 
     A   B C 
---------- ---------- - 
     1   2 A 
     2   1 A 
     2   3 C 
     3   4 D 

tôi xem xét, các hồ sơ {1,2, A} và {2, 1, A} như trùng lặp. Tôi cần chọn và tạo ra bộ hồ sơ dưới đây:

  A   B C      A   B C 
---------- ---------- -    ---------- ---------- - 
     1   2 A   or   2   1 A 
     2   3 C      2   3 C 
     3   4 D      3   4 D 

Tôi đã thử các truy vấn dưới đây. Nhưng không có kết quả.

select t1.* 
from t6 t1 
, t6 t2 
where t1.a <> t2.b 
and t1.b <> t2.a 
and t1.rowid <> t2.rowid 
/

     A   B C 
---------- ---------- - 
     1   2 A 
     2   1 A 
     2   1 A 
     2   3 C 
     3   4 D 
     3   4 D 

6 rows selected. 

Hoặc ngay cả điều này:

select * 
from t6 t1 
where exists (select * from t6 t2 where t1.a <> t2.b and t1.b <> t2.a) 
/
     A   B C 
---------- ---------- - 
     1   2 A 
     2   1 A 
     2   3 C 
     3   4 D 

Cả hai đã không làm việc.

Cơ sở dữ liệu sẽ là Oracle 10g. Tìm kiếm một giải pháp SQL thuần túy. Mọi trợ giúp đều được đánh giá cao.

+0

biết chính xác là bạn đang cố gắng để thực hiện? Vui lòng mở rộng về điều này. – simchona

+0

Tôi cần một SQL để tạo tập bản ghi {1, 2, A}, {2, 3, C} và {3, 4, D}. Đối với tôi {1, 2, A} và {2, 1, A} là các bản ghi trùng lặp và tập kết quả chỉ có một bộ (hoặc {1, 2, A} hoặc {2, 1, A}, nhưng không phải là cả hai) –

+0

Chỉ cần rõ ràng, bằng cách "xóa", bạn có nghĩa là * bộ lọc từ tập hợp kết quả * thay vì * xóa *. – APC

Trả lời

6

Sử dụng các hàm GREATEST() và LEAST() để xác định các giá trị chung trên nhiều cột. Sau đó, sử dụng DISTINCT để loại bỏ các bản sao.

select distinct least(a, b) as a 
     , greatest(a, b) as b 
     , c 
from t6 

Điều này cung cấp cho bạn bộ hồ sơ chính xác mà bạn đã yêu cầu. Nhưng mọi thứ sẽ trở nên phức tạp hơn nếu bạn cần bao gồm các cột khác từ T6.


"Nhưng tôi đã tự hỏi nếu điều này sẽ làm việc cho các lĩnh vực VARCHAR2 cũng?"

Có nhưng nó sẽ sử dụng giá trị ASCII để xác định thứ tự, không phải lúc nào bạn mong đợi (hoặc mong muốn).

"Ngoài ra, bảng T6 của tôi có thể có hàng chục nghìn bản ghi".

Điều đó thực sự không có nhiều dữ liệu theo thuật ngữ ngày nay. DISTINCT sẽ gây ra một sắp xếp, có thể vừa với bộ nhớ trừ khi AB thực sự là các cột VARCHAR2 dài - nhưng có lẽ ngay cả sau đó.

Nếu đây là một truy vấn bạn sẽ muốn chạy nhiều thì bạn có thể xây dựng một chỉ số dựa trên chức năng để đáp ứng nó:

create index t6_fbi on t6(least(a, b) 
          , greatest(a, b) 
          , c) 
/

Nhưng tôi sẽ thực sự chỉ bận tâm nếu bạn có một chính hãng vấn đề hiệu suất với truy vấn.

+0

Cảm ơn @APC, tôi không thể kiểm tra điều này ngay bây giờ. Nhưng tôi đã tự hỏi nếu điều này sẽ làm việc cho các lĩnh vực VARCHAR2 cũng?Ngoài ra, bảng T6 của tôi có thể có hàng chục nghìn hồ sơ .. Tôi đánh giá cao phản ứng của bạn, nhưng vẫn Stackoverflow không cho phép tôi lên bầu bạn. :( –

0

Nếu thứ tự của cột A và B không quan trọng và luôn luôn chứa một số nguyên, làm thế nào về:

select distinct 
    least(a, b) as a, 
    greatest(a, b) as b, 
    c 
from 
    t6 
Các vấn đề liên quan