TSQL - Full Outer Join über 3 Tabellen

Ghost_Rider_R

Lt. Junior Grade
Dabei seit
Nov. 2009
Beiträge
412
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

TheOtherSide

Ensign
Dabei seit
Juli 2008
Beiträge
203
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:

Oelepoeto

Cadet 4th Year
Dabei seit
Juli 2019
Beiträge
105
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)

Ghost_Rider_R

Lt. Junior Grade
Ersteller dieses Themas
Dabei seit
Nov. 2009
Beiträge
412
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.
 

Oelepoeto

Cadet 4th Year
Dabei seit
Juli 2019
Beiträge
105
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 :-)
 

parats

Lt. Junior Grade
Dabei seit
Okt. 2018
Beiträge
403
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?
 
Top