2010-12-23 10 views
2

wie relationale Tabellen 3 mit der Struktur verbinden:wie beizutreten 3 relationale Tabellen

t1 | id 
t2 | id | rating 
t3 | source_id | relation 

t3 speichert die Daten von einem Feld, die T1 und T2 beide verwenden. Das Feld source_id kann die ID von t1 oder die ID von t2 sein.

input : t1 id 
output : t2 rating 

ein Beispiel:

**t1** 

id | 
--------- 
42 | 

**t2** 

id | rating 
------------- 
37 | 9.2 

**t3** 

id | source_id 
-------------- 
42 | 1 
37 | 1 
26 | 2 
23 | 1 

, was ich will, ist 9.2-Ausgang mit 42-Eingang zu erhalten.

können Sie das in einer SQL-Abfrage tun?

+0

Was bedeutet 'source_id'? Es ist '1' für' 42' und '37', obwohl sie zu verschiedenen Tabellen gehören. – Quassnoi

+0

Ihre Tabellenstruktur ist unklar. 'source_id' scheint nicht das zu tun, was Sie beschreiben. Für die gewünschten Joins sollte es eine Relation geben, die das Tupel enthält (42, 37). – OrangeDog

+0

Ich habe es auch nicht verstanden. Und warum sollte die Ausgabe für 42 9,2 sein? Ist 9.2 mit 37 verwandt? // Oh, ich glaube, ich habe es verstanden. Der Ausgang für 42, 37 und 23 sollte 9.2 sein. Ist es? – Michael

Antwort

2

Diese Abfrage wird Sie die gewünschte Ausgabe auf Ihre Daten geben, glaube allerdings nicht, dass es in Ihrem Modell korrekt ist:

SELECT t2.rating 
FROM t1 
JOIN t3 t31 
ON  t31.id = t1.id 
JOIN t3 t32 
ON  t32.source_id = t31.source_id 
JOIN t2 
ON  t2.id = t32.id 
WHERE t1.id = 42 
+0

Sie haben Recht mit der source_id, es ist nicht klar, aber es muss auch nicht. Wie Sie sich vorstellen können, wenn die Quell-ID 1 ist, dann ist 42 und 37 verbunden. – orioncabbar

+0

@orioncabbar: Was ist, wenn Sie ID '42' sowohl in' t1' als auch in 't2' haben? – Quassnoi

+0

eigentlich ist es möglich, aber es ist nicht wichtig für mich, ich will nur ein Ergebnis, also begrenzen Sie es mit einem. übrigens habe ich deine lösung versucht, es gab ein resukt aber ein falsches. Ich versuche zu verstehen, wie es möglich ist. – orioncabbar

1

ich die Lösung gefunden, was denken Sie?

SELECT t2.rating 
FROM t3 AS t3 
inner join t1 AS t1 on t1.id = t3.id 
inner join (SELECT source_id, rating 
FROM t3 AS t32 
inner join t2 AS review on t2.id = t32.id) as second on second.source_id = t3.source_id 
where t1.id = 42 limit 0,1 
+0

Beantworten Sie Ihre eigene Frage und stimmen Sie für sich selbst ist immer verdächtig. Ist das eine echte Frage oder ein kryptisches Rätsel über nicht-relationale Nicht-Tabellen? – PerformanceDBA

2

Sie "relationalen Tabellen" sind eine Katastrophe; Der SQL-Code (SQL dient zum Navigieren in relationalen Datenbanken) ist ein weiterer, niemals vollständiger oder stabiler. Codierungsprobleme sind Folgeprobleme zweiter Ordnung, die Fehler in der ersten Reihenfolge identifizieren.

Zuerst normalisieren und modellieren Sie Ihre Daten genau für das relationale DBMS, in das Sie es eingefügt haben; und damit Sie die SQL Relational Language verwenden können. Dann wird der Code einfach, einfach, unkompliziert und vollständig sein.

Wenn Sie möchten, dass ich die Daten modelliere, gut. Aber ich brauche mehr Informationen als kryptische Id Spalten; Ich brauche Namen von Entitäten und Spalten, was sie bedeuten, wie sie tatsächlich miteinander verwandt sind.

Antworten auf Kommentare

Ja, man kann sicherlich eine Spalte, die einen Fremdschlüssel mehr als eine übergeordnete Tabelle verweisen ist. Aber Sie können nicht (in der relationalen Datenbank) haben eine entweder eine oder eine andere Elterntabelle: das wird zu Waisen, Jungfern, und alle Arten von leicht vermeidbaren Kodierung Horrors führen.

+3

+1 Das muss wirklich gesagt werden. Es gibt fast nie einen Grund, eine "Fremdschlüssel" -Spalte zu haben, die auf zwei verschiedene Tabellen verweisen kann. Das deutet normalerweise auf schlechtes Design oder unvollständige Normalisierung hin. Es ist oft verlockend, OO in einem RDBMS zu implementieren. Aber nach ein bisschen Nachhilfe gibt es noch bessere Wege. – siride

+0

Ja, ich verstehe was du mit der Klarstellung meinst. Das ist natürlich nicht das, was hier vor sich geht. – siride

+0

@siride. * Das ist eindeutig nicht das, was hier vorgeht. * Nicht sicher, was du meinst: der erste Teil meiner Antwort ist ** nicht ** hier; Der zweite Teil ** ist ** hier los. – PerformanceDBA