TSQL - Full Outer Join über 3 Tabellen

Ghost_Rider_R

Lieutenant
Registriert
Nov. 2009
Beiträge
752
Hallo zusammen,

wie macht man denn einen FULL OUTER JOIN über 3 Tabellen, ohne dass Zeilen mehrfach angezeigt werden?
Ich habe meine Beispiel-Abfrage angehängt (mit anderen Tabellennamen).

Ein einfaches Beispiel: (und es ist nur ein Beispiel, die Tabellen würde man so natürlich nicht aufsetzten)

Man gehe davon aus, dass es 3 Tabellen gibt z.B. Tabelle Artikel, ArtikelFarbe und Artikelgröße. In jeder Tabelle gibt es als Schlüssel die Spalte ArtikelNr und dann die Spalte Bezeichnung (Tabelle Artikel), die Spalte Farbe (Tabelle ArtikelFarbe) und in der letzten Tabelle die Spalte Größe (Tabelle Artikelgröße).

Mein Stand wäre aktuell wie folgt:

SELECT Artikel.ArtikelNr,
ArtikelFarbe.ArtikelNr,
ArtikelGröße.ArtikelNr

FROM Artikel
FULL OUTER JOIN ArtikelFarbe ON Artikel.ArtikelNr = ArtikelFarbe.ArtikelNr
FULL OUTER JOIN ArtikelGröße ON Artikel.ArtikelNr = ArtikelGröße.ArtikelNr
AND ArtikelFarbe.ArtikelNr = ArtikelGröße.ArtikelNr

Sofern in allen drei Tabellen ein Datensatz vorhanden ist bekomme ich genau eine Zeile zurück (wie ich es auch möchte), wenn aber jetzt in einer Tabelle ein Wert fehlt, bekomme ich den Datensatz mehrfach zurück, Gruppieren lässt sich das leider auch nicht.

Hat da jemand eine Idee wie man sowas macht?

Bitte keine Workarounds, die hab ich schon und funktionieren auch aber ich suche die ,,saubere" Lösung, wenn es denn eine gibt :-)

Vielen Dank und LG

Ruff
 

Anhänge

  • a.jpg
    a.jpg
    19,6 KB · Aufrufe: 3.568
  • SQL.jpg
    SQL.jpg
    112,3 KB · Aufrufe: 3.565
Hallo zusammen,

dass SQL das du suchst sollte ungefähr so aussehen:

SQL:
SELECT
    tab_a.ArtikelNr AS tab_a_ArtikelNr,
    tab_b.ArtikelNr AS tab_b_ArtikelNr,
    tab_c.ArtikelNr AS tab_c_ArtikelNr,
    NVL(tab_a.ArtikelNr, NVL(tab_b.ArtikelNr,tab_c.ArtikelNr)) AS combined_ArtikelNr
FROM
    Artikel tab_a
FULL OUTER JOIN ArtikelFarbe tab_b
    ON tab_a.ArtikelNr = tab_b.ArtikelNr
FULL OUTER JOIN ArtikelGröße as tab_c
    ON tab_c.ArtikelNr = tab_a.ArtikelNr
        OR tab_c.ArtikelNr = tab_b.ArtikelNr

Wenn du allerdings nur die ArtikelNr über alle drei Tabellen haben willst, dann geht dies auch einfacher, schneller und Ressourcenschonender mit:

SQL:
WITH W_ARTIKEL_NR AS (
    SELECT DISTINCT
        ArtikelNr
    FROM
        Artikel
    UNION
    SELECT DISTINCT
        ArtikelNr
    FROM
        ArtikelFarbe
    UNION
    SELECT DISTINCT
        ArtikelNr
    FROM
        ArtikelGröße
)
SELECT DISTINCT
    ArtikelNr
FROM
    W_ARTIKEL_NR


Viele Grüße



EDIT
- Tabellenabkürzungen hinzugefügt, aber nicht benutzt.

EDIT2
- Kombinierte Spalte mit NVL hinzugefügt, als Showcase

EDIT3
- DISTINCT zum UNION hinzugefügt, als besseres Beispiel + SQL mit WITH-Clause umgewandelt
 
Zuletzt bearbeitet:
Hallo,
würde es in etwa so machen:

SQL:
WITH T1 AS
(
    SELECT 1 AS ArtikelNr, 'x' AS Attribut
    UNION ALL SELECT 2, 'y'
)
, T2 AS
(
    SELECT 1 AS ArtikelNr, 'rot' AS Farbe
    UNION ALL SELECT 3 AS ArtikelNr, 'gruen' AS Farbe
)
, T3 AS
(
    SELECT 1 AS ArtikelNr, 'vorraetig' AS Vorrat
    UNION ALL SELECT 4, 'ausverkauft'
)

SELECT COALESCE(t1.[ArtikelNr],[t2].[ArtikelNr],[t3].[ArtikelNr]) AS ArtikelNr
    , t1.[Attribut]
    , [t2].[Farbe]
    , [t3].[Vorrat]
FROM T1 t1
FULL OUTER JOIN T2 t2
    ON [t2].[ArtikelNr] = [t1].[ArtikelNr]
FULL OUTER JOIN T3 t3
    ON [t3].[ArtikelNr] = [t1].[ArtikelNr]
GROUP BY COALESCE(t1.[ArtikelNr], [t2].[ArtikelNr], [t3].[ArtikelNr]),[t1].[Attribut],[t2].[Farbe],[t3].[Vorrat]

Ich nehme also aus meine Beispieldaten T1, T2, T3 die Spalte ArtikelNr als logischer Key an, die restlichen Spalten als Attribute die jeweils nur ein mal vorkommen.

Wenn bestimmte Spalten in mehrere Quellen vorkommen dann musst du überlegen, welche "Priorität" haben, und diese entsprechend im Coalesce vorreihen
 
Zuletzt bearbeitet: (Nachtrag)
Hallo zusammen, vielen Dank für Eure Hilfe,

TheOtherSide -> Erstes Statement war die Lösung

Das merkwürdige ist, ich könnte schwören das habe ich genau so 1000x am Freitag probiert und habe immer zwei Datensätze zurück bekommen, sehr merkwürdig.
 
was ist denn NVL? ist laut mein Management Studio auf SQL Server 2016 keine Funktion..?
Schaut nach ISNULL aus, würde sagen, dass COALESCE mit den 3 Spalten sauberer ist.

zur Info: Union ist immer auch Distinct, das ist also redundant.
Ergänzung ()

Ah, das ist Oracle :-)
 
Nur zum Verständnis, du hast den natürlichen Schlüssel deiner Artikel als Referenz in den Attributstabellen oder war dein Beispiel echt so unglücklich formuliert?
 
Zurück
Oben