2012-07-29 42 views
12

Tôi có hai cột, nguồn và đích trong bảng Siêu liên kết, để lưu trữ nguồn và đích của siêu liên kết.Chọn kết hợp riêng biệt từ hai cột

source | destination 
-------------------- 
    a | b 
    b | c 
    c | d 
    c | b 

Có hai siêu liên kết liên quan đến cả b và c. Sự khác biệt giữa hai siêu liên kết là hướng của siêu liên kết. Tuy nhiên, mục tiêu của tôi là truy xuất các siêu liên kết duy nhất, bất kể hướng nào. Vì vậy, đối với các siêu liên kết như từ b đến c và từ c đến b, tôi chỉ muốn chọn một trong số chúng. Bất kỳ ai cũng sẽ làm.

Vì vậy, kết quả của tôi sẽ giống như thế này:

source | destination 
-------------------- 
    a | b 
    b | c 
    c | d 

Cho đến nay tôi có thể thực hiện điều này trong Java, với một số chế biến trước khi tôi thực hiện câu lệnh SQL sử dụng JDBC. Tuy nhiên, điều này sẽ rất tẻ nhạt khi bảng trở nên rất lớn.

Tôi tự hỏi nếu có anyway tôi có thể làm điều này trong SQL để thay thế.

Tôi đã thử SELECT DISTINCT source,destination FROM Hyperlink nhưng nó trả về cho tôi các hoán vị duy nhất. Tôi cần sự kết hợp độc đáo.

Cảm ơn!

+2

Nếu bạn đăng mã, XML hoặc mẫu dữ liệu, ** XIN ** làm nổi bật những dòng trong trình soạn thảo văn bản và bấm vào nút "mã mẫu" ('{}') trên thanh công cụ của trình soạn thảo để định dạng và cú pháp độc đáo làm nổi bật nó! Sau đó, bạn không cần bất kỳ thẻ '
' và ' ' lộn xộn nào! –

+2

tuyệt vời, cảm ơn mẹo! rất khó để sử dụng các thẻ lộn xộn. – paperclip

+1

cảm ơn bạn đã chỉnh sửa, Arkain! – paperclip

Trả lời

3

Đây là một cách dễ dàng đạt được với ít nhất() và lớn nhất() điều hành, nhưng như MySQL không hỗ trợ chúng, bạn cần phải sử dụng một cấu trúc TRƯỜNG HỢP để có được cái nhỏ hơn/lớn hơn. Với hai cột này là ok, nhưng giải pháp này được khá lộn xộn một lần nữa cột được tham gia

select distinct 
      case 
      when source < destination then source 
      else destination 
      end as source, 
      case 
      when source > destination then source 
      else destination 
      end as destination 
from hyperlinks 
+0

Cái này phù hợp với tôi. Tôi chỉ làm việc với hai cột để giải pháp này là đủ tốt. Cảm ơn! – paperclip

1

Bạn có thể sử dụng sự kết hợp của hai tham gia truy vấn riêng biệt như vậy:

SELECT 
lhs.source, lhs.destination 
FROM Hyperlink lhs 
LEFT OUTER JOIN Hyperlink rhs 
ON rhs.source = lhs.destination 
WHERE rhs.source IS NULL 
UNION 
SELECT 
lhs.source, lhs.destination 
FROM Hyperlink lhs 
JOIN Hyperlink rhs 
ON rhs.source = lhs.destination 
WHERE rhs.destination <> lhs.source 
ORDER BY source; 

Truy vấn đầu tiên được các liên kết mà không có nguồn gốc là điểm đến, thứ hai được các trận đấu mà có nguồn như đích đến, nhưng đối lập khác nhau. Nó có thể không phải là triển khai nhanh nhất nhưng đảm bảo bạn có các chỉ mục trên cột nguồn và đích sẽ giúp nó cùng, cho dù nó sẽ có hiệu suất cho bạn hay không phụ thuộc vào bảng Hyperlink lớn hay có khả năng nhận được.

2

Hãy thử truy vấn sau đây:

SELECT DISTINCT source, destination FROM hyperlink 
MINUS 
SELECT destination, source FROM hyperlinks WHERE source < destination; 

này làm việc cho Oracle. Nếu bạn đang sử dụng PostgreSQL, DB2 hoặc TSQL, hãy sử dụng từ khóa EXCEPT thay vì MINUS.

EDIT: Không có tương đương với các từ khóa này trong MySQL. Bạn sẽ phải làm việc xung quanh nó bằng cách chọn các giá trị theo gợi ý của Jim Riordan. Tôi sẽ không xóa câu trả lời của tôi trong trường hợp nếu có ai cần làm điều đó trong bất kỳ bốn DBMS chính nào khác.

+0

Tôi đang sử dụng MySQL, nhưng cảm ơn câu trả lời của bạn. Nếu không nhầm, trong MySQL, nó phải là UNION thay vì MINUS. Cảm ơn một lần nữa! – paperclip

+0

@paperclip theo như tôi biết, một 'UNION' kết hợp các hàng từ các bảng và loại bỏ các bản sao. Cái này khác. 'MINUS' là một thao tác được thiết lập để xóa một hàng khỏi tập hợp cho mọi hàng giống nhau trong một tập hợp khác. '(A, B, C) UNION (C, D)' cho '(A, B, C, D)'. Nhưng '(A, B, C) TRỪ (C, D)' trả về '(A, B)'. Bạn không thể thay thế một cái bằng cái kia, bạn phải thay đổi các câu lệnh SELECT một cách đáng kể. – toniedzwiedz

0

tôi đã cố gắng truy vấn này và nó làm việc cho tôi

SELECT table1.Source, table1.Destination FROM dbo.hyperlinks table1 WHERE NOT EXISTS 
(SELECT * FROM hyperlinks table2 WHERE table1.Source = table2.Destination AND table2.Source = table1.Destination) 

UNION 

SELECT TOP 1 table1.Source, table1.Destination FROM hyperlinks table1 WHERE 
    (SELECT COUNT(*) FROM hyperlinks table2 WHERE table1.Source = table2.Destination AND table2.Source = table1.Destination) > 0 
+0

Tôi không hiểu tuyên bố của bạn. Bảng 2 đến từ đâu? – paperclip

+0

đây là tên bí danh cho bảng siêu liên kết! bởi vì tôi đã sử dụng bảng siêu liên kết nhiều hơn một lần trong truy vấn của mình, tôi phải sử dụng tên bí danh cho nó. Tôi đã sử dụng test1 và test2. bạn có thể sử dụng bất kỳ tên nào bạn muốn! – Azade

+0

Ồ, tôi hiểu rồi. :) – paperclip

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