Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bidirectional outer join

Tags:

sql

mysql

Suppose we have a table A:

itemid mark
1      5
2      3

and table B:

itemid mark
1      3
3      5

I want to join A*B on A.itemid=B.itemid both right and left ways. i.e. result:

itemid A.mark B.mark
1      5      3
2      3      NULL
3      NULL   5

Is there a way to do it in one query in MySQL?

like image 414
elephantum Avatar asked Aug 13 '08 09:08

elephantum


People also ask

What are the three types of outer join?

There are three types of outer joins: left outer join, right outer join, and full outer join.

What is SQL join (+) means?

An SQL Join is an operation that combines records from two or more tables. This is done by matching keys between tables.

Is MySQL support full outer join?

MySQL does not support full outer join out of the box, unlike other databases such as PostgreSQL, and SQL Server. So you will need to do a full outer join using a combination of other join types such as LEFT JOIN ad RIGHT JOIN that are supported in MySQL.

What is outer joining?

Outer joins are joins that return matched values and unmatched values from either or both tables. There are a few types of outer joins: LEFT JOIN returns only unmatched rows from the left table, as well as matched rows in both tables.


2 Answers

It's called a full outer join and it's not supported natively in MySQL, judging from its docs. You can work around this limitation using UNION as described in the comments to the page I linked to.

[edit] Since others posted snippets, here you go. You can see explanation on the linked page.

SELECT *
FROM A LEFT JOIN B ON A.id = B.id
UNION ALL
SELECT *
FROM A RIGHT JOIN B ON A.id = B.id
WHERE A.id IS NULL
like image 77
Nickolay Avatar answered Oct 20 '22 17:10

Nickolay


Could do with some work but here is some sql

select distinct T.itemid, A.mark as "A.mark", B.mark as "B.mark"
    from (select * from A union select * from B) T 
    left join A on T.itemid = A.itemid 
    left join B on T.itemid = B.itemid;

This relies on the left join, which returns all the rows in the original table (in this case this is the subselect table T). If there are no matches in the joined table, then it will set the column to NULL.

like image 39
roo Avatar answered Oct 20 '22 16:10

roo