How to do a FULL OUTER JOIN in MySQL?

2018-12-30 23:30发布

I want to do a Full Outer Join in MySQL. Is this possible? Is a Full Outer Join supported by MySQL?

14条回答
妖精总统
2楼-- · 2018-12-30 23:46

Modified shA.t's query for more clarity:

-- t1 left join t2
SELECT t1.value, t2.value
FROM t1 LEFT JOIN t2 ON t1.value = t2.value   

    UNION ALL -- include duplicates

-- t1 right exclude join t2 (records found only in t2)
SELECT t1.value, t2.value
FROM t1 RIGHT JOIN t2 ON t1.value = t2.value
WHERE t2.value IS NULL 
查看更多
裙下三千臣
3楼-- · 2018-12-30 23:49

You don't have FULL JOINS on MySQL, but you can sure emulate them.

For a code SAMPLE transcribed from this SO question you have:

with two tables t1, t2:

SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id

The query above works for special cases where a FULL OUTER JOIN operation would not produce any duplicate rows. The query above depends on the UNION set operator to remove duplicate rows introduced by the query pattern. We can avoid introducing duplicate rows by using an anti-join pattern for the second query, and then use a UNION ALL set operator to combine the two sets. In the more general case, where a FULL OUTER JOIN would return duplicate rows, we can do this:

  SELECT * FROM t1
  LEFT JOIN t2 ON t1.id = t2.id
  UNION ALL
  SELECT * FROM t1
  RIGHT JOIN t2 ON t1.id = t2.id
  WHERE t1.id IS NULL
查看更多
有味是清欢
4楼-- · 2018-12-30 23:49

In SQLite you should do this:

SELECT * 
FROM leftTable lt 
LEFT JOIN rightTable rt ON lt.id = rt.lrid 
UNION
SELECT lt.*, rl.*  -- To match column set
FROM rightTable rt 
LEFT JOIN  leftTable lt ON lt.id = rt.lrid
查看更多
大哥的爱人
5楼-- · 2018-12-30 23:49

None of the above answers are actually correct, because they do not follow the semantics when there are duplicated values.

For a query such as (from this duplicate):

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

The correct equivalent is:

SELECT t1.*, t2.*
FROM (SELECT name FROM t1 UNION  -- This is intentionally UNION to remove duplicates
      SELECT name FROM t2
     ) n LEFT JOIN
     t1
     ON t1.name = n.name LEFT JOIN
     t2
     ON t2.name = n.name;

If you need for this to work with NULL values (which may also be necessary), then use the NULL-safe comparison operator, <=> rather than =.

查看更多
皆成旧梦
6楼-- · 2018-12-30 23:49

It is also possible, but you have to mention the same field names in 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
查看更多
倾城一夜雪
7楼-- · 2018-12-30 23:52
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
查看更多
登录 后发表回答