Как сделать FULL OUTER JOIN в MySQL? - PullRequest
568 голосов
/ 25 января 2011

Я хочу сделать полное внешнее соединение в MySQL.Это возможно?Поддерживается ли полное внешнее соединение MySQL?

Ответы [ 14 ]

0 голосов
/ 23 мая 2017

Я исправляю ответ, и работы включают все строки (на основе ответа Павла Лекича)

    (
    SELECT a.* FROM tablea a
    LEFT JOIN tableb b ON a.`key` = b.key
    WHERE b.`key` is null
    )
    UNION ALL
    (
    SELECT a.* FROM tablea a
    LEFT JOIN tableb b ON a.`key` = b.key
    where  a.`key` = b.`key`
    )
    UNION ALL
    (
    SELECT b.* FROM tablea a
    right JOIN tableb b ON b.`key` = a.key
    WHERE a.`key` is null
    );
0 голосов
/ 09 февраля 2017

Ответ:

SELECT * FROM t1 FULL OUTER JOIN t2 ON t1.id = t2.id;

Может быть воссоздано следующим образом:

 SELECT t1.*, t2.* 
 FROM (SELECT * FROM t1 UNION SELECT name FROM t2) tmp
 LEFT JOIN t1 ON t1.id = tmp.id
 LEFT JOIN t2 ON t2.id = tmp.id;

Использование ответа UNION или UNION ALL не охватывает крайний случай, когда в базовых таблицах есть дублированные записи.

Пояснение:

Существует крайний случай, который UNION или UNION ALL не могут покрыть. Мы не можем проверить это на mysql, так как он не поддерживает FULL OUTER JOIN, но мы можем проиллюстрировать это на базе данных, которая его поддерживает:

 WITH cte_t1 AS
 (
       SELECT 1 AS id1
       UNION ALL SELECT 2
       UNION ALL SELECT 5
       UNION ALL SELECT 6
       UNION ALL SELECT 6
 ),
cte_t2 AS
(
      SELECT 3 AS id2
      UNION ALL SELECT 4
      UNION ALL SELECT 5
      UNION ALL SELECT 6
      UNION ALL SELECT 6
)
SELECT  *  FROM  cte_t1 t1 FULL OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2;

This gives us this answer:

id1  id2
1  NULL
2  NULL
NULL  3
NULL  4
5  5
6  6
6  6
6  6
6  6

Решение UNION:

SELECT  * FROM  cte_t1 t1 LEFT OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2
UNION    
SELECT  * FROM cte_t1 t1 RIGHT OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2

Дает неправильный ответ:

 id1  id2
NULL  3
NULL  4
1  NULL
2  NULL
5  5
6  6

СОЮЗ ВСЕ решение:

SELECT  * FROM cte_t1 t1 LEFT OUTER join cte_t2 t2 ON t1.id1 = t2.id2
UNION ALL
SELECT  * FROM  cte_t1 t1 RIGHT OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2

тоже неверно.

id1  id2
1  NULL
2  NULL
5  5
6  6
6  6
6  6
6  6
NULL  3
NULL  4
5  5
6  6
6  6
6  6
6  6

Тогда как этот запрос:

SELECT t1.*, t2.*
FROM (SELECT * FROM t1 UNION SELECT name FROM t2) tmp 
LEFT JOIN t1 ON t1.id = tmp.id 
LEFT JOIN t2 ON t2.id = tmp.id;

Дает следующее:

id1  id2
1  NULL
2  NULL
NULL  3
NULL  4
5  5
6  6
6  6
6  6
6  6

Порядок отличается, но в остальном совпадает с правильным ответом.

0 голосов
/ 03 февраля 2014

Это также возможно, но вы должны указать те же имена полей в select.

SELECT t1.name, t2.name FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION
SELECT t1.name, t2.name FROM t2
LEFT JOIN t1 ON t1.id = t2.id
0 голосов
/ 24 октября 2013
SELECT
    a.name,
    b.title
FROM
    author AS a
LEFT JOIN
    book AS b
    ON a.id = b.author_id
UNION
SELECT
    a.name,
    b.title
FROM
    author AS a
RIGHT JOIN
    book AS b
    ON a.id = b.author_id
...