2016-05-02 7 views
0

Ich habe zwei Tabellen "TestItem" und "Connector", wo Connector für die Verknüpfung zweier Elemente in "TestItem" verwendet wird. Ich habe zwei Fragen in priorisierter Reihenfolge. Aber zögern Sie nicht, alternative Ansätze vorzuschlagen. Ich bin offen für Vorschläge, um meine Herangehensweise an das, was ich hier erreichen möchte, komplett zu überdenken.SQL verbinden beide Wege zu einem Ergebnis

Frage 1) Wie Beziehungen in beiden Richtungen in dem gleichen Ergebnis kehrte bekommen

Frage 2) Wie die effizienteste Art und Weise für bestimmte Elemente filtern

Q1) Zwei Tabellen

Tabelle: "TestItem"

ID, ITEM 
1, "John Doe" 
2, "Peggy Sue" 
3, "Papa Sue" 

Tabelle: „Connector“

MOTHER, CHILD 
    1,2 

Der Stecker Tabelle wird für verschiedene Zwecke verwendet werden (siehe unten), aber dies ist ein destillierter Szenario für die gleiche Art Verbindung, wie zum Beispiel der Ehe. Wenn "John Doe" mit "Peggy Sue" verheiratet ist, sollte diese Information auch ausreichen, um "Peggy Sue" als verheiratet mit "John Doe" zurückzugeben. Ich kann dies in zwei Abfragen tun, aber für die Effizienz (vor allem in Bezug auf meine Frage 2) würde ich es in einer Abfrage zu schätzen wissen, so dass eine Implementierung nicht davon abhängt, wie die Verbindung definiert ist. Was ist der effizienteste Weg, dies zu tun?

Zwei Abfragen nähern, um zu veranschaulichen, wie die Daten abgerufen werden können, aber wie eine Verbindung auf die eine oder andere Weise verpasst wird.

//Connector through "mother"-part SELECT ITEM, SUBITEM FROM TestItem 
INNER JOIN (
    SELECT MOTHER, ITEM AS SUBITEM 
    FROM Connector 
    INNER JOIN TestItem ON Connector.CHILD = TestItem.ID 
    ) AS SUB ON TestItem.ID = SUB.MOTHER 

    /* WHERE ITEM = "John Doe" return "Peggy Sue" => Correct 
    WHERE ITEM = "Peggy Sue" return nothing => Wrong 
    */ 

//Connector through "child"-part SELECT ITEM, SUBITEM FROM TestItem 
INNER JOIN (
    SELECT CHILD, ITEM AS SUBITEM 
    FROM Connector 
    INNER JOIN TestItem ON Connector.MOTHER= TestItem.ID 
    ) AS SUB ON TestItem.ID = SUB.CHILD 


    /* WHERE ITEM = "John Doe" return nothing => Wrong 
    WHERE ITEM = "Peggy Sue" return "John Doe" => Correct 
    */ 

Q2) Wenn die beiden Ansätze in einem Ergebnis zurückgegeben werden, erhöht sich möglicherweise die Menge der Daten und damit die Leistung. Wenn ich mich auf Peggy Sue konzentriere, gehe ich davon aus, dass nur die relevanten Daten so früh wie möglich sortiert werden, um die Leistung zu verbessern. Gibt es eine gute Möglichkeit, dies von der obersten Ebene aus zu tun, oder wird für jede Unterabfrage ein zusätzliches WHERE benötigt?


PS: Einige weitere Informationen der größeren Perspektive. Ich plane, die Connector-Tabelle für verschiedene Zwecke zu verwenden, sowohl für den gleichen Typ, wie Kollegen, Familie, Freunde, etc., aber auch für hierarchische Verbindungstypen wie Mutter/Kind, Leiter/Mitarbeiter, Land/Stadt. Lösungen, die die Mutter/Kind-Verbindung eliminieren, können daher meinem größeren Zweck nicht gerecht werden. Im Grunde frage ich, wie man die gleiche Art von Verbindungen behandelt, ohne die Möglichkeit zu verlieren, die gleiche Architektur und Daten für hierarchische Verbindungen zu verwenden. Peggy Sue kann durch den gleichen Datensatz als Tochter von Papa Sue durch die Beziehung definiert werden

Mother, Child, Mother_type, Child_type 
3, 2, Father, Daughter 
1, 2, Married to, Married to 

(Aber das ist, wie auf der Seite erwähnt, was ich Ihr Interesse hier.)

+0

SQL-Fragen werden leicht beantwortet, wenn eine erwartete Ausgabe zur Verfügung gestellt. Außerdem ist es verwirrend, die Eingabedaten mit Mutter und Kind zu sehen, aber über einen Fall mit einer Ehe zu sprechen. – Edu

+0

Hallo. Entschuldigung für die Verwirrung. Ich glaube, meine erwartete Leistung war klar.Ich möchte eine Abfrage für ein Element haben und eine Verbindung erhalten, unabhängig davon, ob die Verbindung von John Doe oder Peggy Sue definiert wurde. Also im Grunde SELECT Item, connectedItem WHERE ITEM = "Peggy Sue" sollte John Doe zurückgeben, aber das wichtige hier ist, dies unabhängig davon zu tun, auf welche Weise die Verbindung in der Connector-Tabelle erfolgt. Also Mutter/Kind sind architektonische Definitionen (Hauptdatensatz vs Unterdatensatz), während "Ehe" ist eine Definition der Verbindung, die in beide Richtungen gleich ist, um zu veranschaulichen, was ich erreichen möchte. –

+0

Vater? Tochter? Dies wird in Ihrer Datenbank nicht erwähnt. – Tobb

Antwort

0

UNION ALL sein könnte was Sie suchen:

select mother.id as connectedToId, 
     mother.item as connectedToItem, 
     'Mother' as role 
from TestItem ti 
    join Connector c on c.child = ti.id 
    join TestItem mother on c.mother = mother.id 
where ti.item = 'John Doe' 
union all 
select child.id as connectedToId, 
     child.item as connectedToItem, 
     'Child' as role 
from TestItem ti 
    join Connector c on c.mother = ti.id 
    join TestItem child on c.child = child.id 
where ti.item = 'John Doe' 
+0

Vielen Dank. Nach der Korrektur eines t.id, der ti.id sein sollte, gab dies die erwarteten Ergebnisse zurück. Als ich das Item zu 'Peggy Sue' in der _TWO_ geändert habe, wo ich bin, habe ich auch die richtigen Ergebnisse in dieser Richtung. Ich nehme an, das beantwortet auch meine Frage 2 :-) –