2012-07-29 17 views
12

Ich habe zwei Spalten, Quelle und Ziel in der Tabelle Hyperlink, um die Quelle und das Ziel von Hyperlinks zu speichern.Wählen Sie unterschiedliche Kombinationen aus zwei Spalten

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

Es gibt zwei Hyperlinks zwischen b und c. Der Unterschied zwischen den beiden Hyperlinks ist die Richtung des Hyperlinks. Mein Ziel ist es jedoch, eindeutige Hyperlinks unabhängig von der Richtung abzurufen. Also für Hyperlinks wie von b nach c und von c nach b möchte ich nur einen von ihnen auswählen. Jeder würde tun.

So sollte meine Ergebnisse wie folgt aussehen:

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

Bisher ich in der Lage bin dies mit einer gewissen Verarbeitung in Java zu implementieren, bevor ich SQL-Anweisungen mit JDBC ausführen. Dies wird jedoch sehr mühsam, wenn der Tisch sehr groß wird.

Ich frage mich, ob es trotzdem gibt, kann ich dies in SQL stattdessen tun.

Ich versuchte SELECT DISTINCT source,destination FROM Hyperlink, aber es gibt mir die einzigartigen Permutationen zurück. Ich brauche die einzigartigen Kombinationen.

Danke!

+2

beteiligt sind Wenn Sie Code schreiben, XML oder Datenproben, ** BITTE ** diese Zeilen im Texteditor markieren, und klicken Sie auf die "code samples" button ('{}') auf der Editor-Toolbar, um sie schön zu formatieren und zu markieren! Dann brauchen Sie keines der unordentlichen '
' und ' ' Tags, entweder! –

+2

toll, danke für den Tipp! Es war schwer, die chaotischen Tags zu benutzen. – paperclip

+1

danke für den Schnitt, Arkain! – paperclip

Antwort

3

Dies mit dem geringsten leicht erreichbar ist() und größten() Operator, sondern als MySQL sie Sie brauchen nicht unterstützt ein CASE-Konstrukt zu verwenden, um den kleineren/größeren zu bekommen. Mit zwei Spalten ist dies in Ordnung, aber diese Lösung wird ziemlich chaotisch einmal mehr Spalten

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

Dieser funktioniert für mich. Ich arbeite nur mit zwei Spalten, also ist diese Lösung gut genug. Vielen Dank! – paperclip

1

Sie die Vereinigung von zwei getrennten Join-Abfragen wie so verwenden können:

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; 

Die erste Abfrage wird die Links, die nicht die Quelle als Ziel haben, erhält der zweite die Spiele, die Quelle als Standard das Ziel, aber verschiedene Gegensätze. Es ist wahrscheinlich nicht die schnellste Implementierung, aber sicherzustellen, dass Sie Indizes für die Quell- und Zielspalten haben, hilft es dabei. Ob es für Sie performant ist, hängt davon ab, wie groß die Hyperlink-Tabelle ist oder wahrscheinlich wird.

2

Versuchen Sie die folgende Abfrage:

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

Dies funktioniert für Oracle. Wenn Sie PostgreSQL, DB2 oder TSQL verwenden, verwenden Sie das Schlüsselwort EXCEPT anstelle von MINUS.

EDIT: Es gibt keine Entsprechung dieser Schlüsselwörter in MySQL. Du musst es umgehen, indem du die Werte auswählst, die Jim Riordan vorgeschlagen hat. Ich werde meine Antwort nicht löschen, falls jemand es in einem der anderen vier großen DBMS tun sollte.

+0

Ich benutze MySQL, aber danke für Ihre Antwort. Wenn nicht falsch, sollte es in MySQL UNION statt MINUS sein. Danke noch einmal! – paperclip

+0

@paperclip so weit ich weiß, eine 'UNION' kombiniert Zeilen aus Tabellen und entfernt Duplikate. Das ist anders. 'MINUS' ist eine Mengenoperation, die für jede identische Zeile in einem anderen Satz eine Zeile aus einem Satz entfernt. "(A, B, C) UNION (C, D)" ergibt "(A, B, C, D)". Aber '(A, B, C) MINUS (C, D)' '' '(A, B)' 'zurück. Sie können nicht einfach nur eines ersetzen, Sie müssten die SELECT-Anweisungen erheblich ändern. – toniedzwiedz

0

habe ich versucht, diese Abfrage und es funktionierte für mich

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

Ich verstehe Ihre Aussage nicht. Woher kommt table2? – paperclip

+0

Dies ist ein Aliasname für die Hyperlink-Tabelle! Da ich die Hyperlink-Tabelle mehrmals in meiner Abfrage verwendet habe, muss ich einen Alias-Namen dafür verwenden. Ich habe test1 und test2 benutzt. Sie können einen beliebigen Namen verwenden! – Azade

+0

Oh, ich verstehe es jetzt. :) – paperclip

Verwandte Themen