User Tools

Site Tools


sql:snippets:fullouterjoin

[SQL] Full Outer Join

MySQl Unterstützt keine FULL OUTER JOIN. Es gibt verschiedene Ansätze wie man das lösen kann. Sehr verbreitet ist die Version mit einem UNION über einen LEFT und einen RIGHT OUTER JOIN.

Beispieldaten

Für meine Beispiele habe ich mal 2 Tabellen erstellet. foj1 - 3.

CREATE TABLE `foj1` (
    `id` BIGINT(20) NOT NULL DEFAULT '0',
    `v1` INT(10) NULL DEFAULT NULL
)
INSERT INTO `foj1` (`id`, `v1`) VALUES (1, 11);
INSERT INTO `foj1` (`id`, `v1`) VALUES (2, 12);
INSERT INTO `foj1` (`id`, `v1`) VALUES (3, 13);
 
CREATE TABLE `foj2` (
    `id` BIGINT(20) NOT NULL DEFAULT '0',
    `v2` INT(10) NULL DEFAULT NULL
)
INSERT INTO `foj2` (`id`, `v2`) VALUES (1, 21);
INSERT INTO `foj2` (`id`, `v2`) VALUES (3, 23);
INSERT INTO `foj2` (`id`, `v2`) VALUES (4, 24);
 
CREATE TABLE `foj3` (
    `id` BIGINT(20) NOT NULL DEFAULT '0',
    `v3` INT(10) NULL DEFAULT NULL
)
INSERT INTO `foj3` (`id`, `v3`) VALUES (3, 33);
INSERT INTO `foj3` (`id`, `v3`) VALUES (5, 35);

So sehen dann die Tabellen aus

foj1
id v1
1 11
2 12
3 13
foj2
id v2
1 21
3 23
4 24
foj3
id v3
3 33
5 35

Lösung mit LEFT OUTER JOIN UNION RIGHT OUTER JOIN

Über 2 Tabellen

SELECT  f1.id, f1.v1, f2.v2
FROM    foj1 f1 LEFT JOIN foj2 f2 ON f1.id = f2.id
UNION 
SELECT  f2.id, f1.v1, f2.v2
FROM    foj1 f1 RIGHT JOIN foj2 f2 ON f1.id = f2.id
id v1 v2
1 11 21
2 12 _NULL_
3 13 23
4 _NULL_ 24

Über 3 Tabellen

Soweit so gut. Aber wenn man mehrere Tabellen zusammensetzen will, wird das schnell mal sehr unübersichtlich.

SELECT a.id, a.v1, a.v2, f3.v3
FROM
	(
		SELECT  f1.id, f1.v1, f2.v2
		FROM    foj1 f1 LEFT JOIN foj2 f2 ON f1.id = f2.id
		UNION 
		SELECT  f2.id, f1.v1, f2.v2
		FROM    foj1 f1 RIGHT JOIN foj2 f2 ON f1.id = f2.id
	) a
	LEFT JOIN foj3 f3 ON a.id = f3.id
UNION	
SELECT f3.id, b.v1, b.v2, f3.v3
FROM
	(
		SELECT  f1.id, f1.v1, f2.v2
		FROM    foj1 f1 LEFT JOIN foj2 f2 ON f1.id = f2.id
		UNION 
		SELECT  f2.id, f1.v1, f2.v2
		FROM    foj1 f1 RIGHT JOIN foj2 f2 ON f1.id = f2.id
	) b
	RIGHT JOIN foj3 f3 ON b.id = f3.id	
id v1 v2 v3
1 11 21 _NULL_
2 12 _NULL_ _NULL_
3 13 23 33
4 _NULL_ 24 _NULL_
5 _NULL_ _NULL_ 35

Lösung über gemeinsamer Key

Wenn alle 3 Tabellen über denselben Schlüssel verknüpft sind, kann man es vereinfachen Dazu nehmen wir mit einem UNION von allen Tabellen die ID und erstellen uns so mal ein Datensatz auf den wir die Tabellen wieder mittels LEFT JOIN anhängen können

SELECT
    ids.id,
    foj1.v1,
    foj2.v2,
    foj3.v3
FROM
    (
        -- Alle ids ausfindig machen
        SELECT DISTINCT id FROM foj1
        UNION DISTINCT SELECT id FROM foj2
        UNION DISTINCT SELECT id FROM foj3
    ) AS ids
    -- und die Daten dazu verknüpfen
    LEFT JOIN foj1 ON ids.id = foj1.id
    LEFT JOIN foj2 ON ids.id = foj2.id
    LEFT JOIN foj3 ON ids.id = foj3.id
id v1 v2 v3
1 11 21 _NULL_
2 12 _NULL_ _NULL_
3 13 23 33
4 _NULL_ 24 _NULL_
5 _NULL_ _NULL_ 35
sql/snippets/fullouterjoin.txt · Last modified: 28.08.2015 09:33:13 by yaslaw