2017-06-08 1 views
0

Ich habe Probleme, herauszufinden, wie eine SQL-Anweisung geschrieben wird, die die gleiche Anzahl von Datensätzen in der linken Tabelle zurückgibt. Die einzige Möglichkeit, Daten aus der richtigen Tabelle zu erhalten, ist die Verwendung einer dritten Tabelle.Join, das alle linken Tabellendatensätze zurückgibt, wenn die rechte Tabelle über eine Verknüpfungstabelle verbunden ist

Zum Beispiel habe ich drei Tabellen, Sites, Adressen und Zugehörigkeiten. Viele Mitgliedschaften können für eine Site aktiv sein (Kontakt, Mailing-Adresse, Eigentümer und Offizieller), aber es ist möglicherweise keine Person oder Adresse mit der Affiliation verbunden. IE. Eine Website kann eine Kontaktperson, aber keine offizielle benannte Person haben, oder einer Website ist möglicherweise noch keine Mailing-Adresse zugewiesen. Die Sites (linke Tabelle) und die Mitgliedschaften sind durch eine gemeinsame ID verbunden. Sites.ID = Affiliations.Site_ID

Die Zugehörigkeiten und Adressen (rechte Tabelle) durch eine ID gemeinsamen Adressdatensatz verknüpft sind Affiliations.Address_RID = Addresses.RID

Die Abfrage ich habe, ist

SELECT A.ID, 
    A.NAME, 
    C.ADDR_1, 
    C.CITY_NAME, 
    C.STATE_CODE, 
    C.POSTAL_CODE 
FROM SITES A, 
    AFFILIATIONS B, 
    ADDRESSES C 
WHERE A.ID = B.SITE_ID 
    AND B.ADDRESS_RID = C.RID 
    AND B.AFFILIATION_TYPE = 'MAILING ADDRESS' 
ORDER BY A.ID 

Die Ergebnisse, die ich erhalte, wenn ich die Standorttabelle allein abfrage, sind 1580 Standortdatensätze. Wenn ich die obige Abfrage nach Mailadressen durchführe, erhalte ich 1386 Datensätze. Ich muss alle 1580 Datensätze mit Nullen für Datensätze zurückgeben, wo Adressen fehlen. Ich mache etwas falsch, aber ich sehe es nicht.

Kommentare?

Dank

+0

Es kann sinnvoller sein, Ihre Logik in zwei oder drei separate Abfragen zu zerlegen, eine temporäre Tabelle zu verwenden und wenn Sie Ihre Logik in SQL klar sehen können, können Sie alle Ihre Unterabfragen kombinieren. Übrigens, Sie haben sich gerade den Tischen angeschlossen, es ist nicht genau klar, was Sie tun. Verwenden Sie das Join-Schlüsselwort und fügen Sie keine where-Klausel hinzu. –

+0

Ich habe mich gefragt, ob die Verwendung von Unterabfragen der richtige Weg wäre. Es gibt tatsächlich 3 weitere Tabellen, die ich für Filter verwende, als ich im Beispiel angegeben habe. Die Abfragen wären 1 für Sites, die Bedingungen in 2 verbundenen Tabellen (1580 Datensätze) erfüllen. 1 für Kontaktinformationen basierend auf den Websites, die zu 1521 Kontakten führen. Und 1 für Postanschriften, die 1386 Datensätze zurückgeben. –

Antwort

0

Sie sollten versuchen, LEFT JOIN und wenn es dann nicht funktioniert, wo Zustand entfernen.

SELECT A.ID, 
    A.NAME, 
    C.ADDR_1, 
    C.CITY_NAME, 
    C.STATE_CODE, 
    C.POSTAL_CODE 
FROM SITES A, 
left join AFFILIATIONS B on A.ID = B.SITE_ID 
left join ADDRESSES C on B.ADDRESS_RID = C.RID 
    WHERE 
    B.AFFILIATION_TYPE = 'MAILING ADDRESS' 
ORDER BY A.ID 
+0

Ihr linker Beitritt zu Mitgliedschaften B ist sinnlos, weil Sie dann ein Prädikat auf B in der where-Klausel anwenden. –

0

Die „alte“ Oracle-Syntax für Outer-Joins ist wie folgt: -

SELECT A.ID, 
    A.NAME, 
    C.ADDR_1, 
    C.CITY_NAME, 
    C.STATE_CODE, 
    C.POSTAL_CODE 
FROM SITES A, 
    AFFILIATIONS B, 
    ADDRESSES C 
WHERE A.ID = B.SITE_ID (+) 
    AND B.ADDRESS_RID = C.RID (+) 
    AND B.AFFILIATION_TYPE (+) = 'MAILING ADDRESS' 
ORDER BY A.ID 

Aber Sie sollten wirklich die ANSI-Syntax verwenden - es ist viel leichter zu sehen ist, was eine Join-Bedingung ist und Was ist ein Filter: -

SELECT A.ID, 
    A.NAME, 
    C.ADDR_1, 
    C.CITY_NAME, 
    C.STATE_CODE, 
    C.POSTAL_CODE 
FROM SITES A 
LEFT JOIN AFFILIATIONS B ON A.ID = B.SITE_ID AND B.AFFILIATION_TYPE = 'MAILING ADDRESS' 
LEFT JOIN ADDRESSES C ON B.ADDRESS_RID = C.RID 
ORDER BY A.ID 

Beachten Sie, dass die Bedingung für den Affiliation-Typ in der Join-Klausel gehen muss. Wenn Sie es in die where-Klausel aufnehmen, geben Sie keine Zeilen zurück, die nicht über den Zugehörigkeitstyp "MAILING ADDRESS" verfügen.

+0

Danke! Ich benutzte immer noch die "alte" Oracle-Syntax, da dies das war, was ich gelernt hatte, und wir haben seit geraumer Zeit kein Upgrade mehr durchgeführt (staatlicher Mangel an Finanzierung, natürlich), so dass ich die ANSI-Syntax nicht verwendete. Es ist viel einfacher zu sehen, was ich mache. –

Verwandte Themen