This looks like a "full outer" join operation. Unfortunately, MySQL doesn't provide syntax to for this operation in a single SELECT statement.
Fortunately, it is possible to emulate a full outer join, using two SELECT statements.
Assuming that the `name` column is the primary key, or at least guaranteed to be unique...
There are essentially three possible conditions for a given name:
- a row exists in both (the unfortunately named) table1 and table2 (e.g. Sara)
- a row exists in table1 but not table2 (e.g. Bill)
- a row exists in table2 but not table1 (e.g. Carl)
(The fourth condition, name value doesn't exist in either table1 or table2, we're not going to concern ourselves with, since there's no row source for e.g. Javier.)
To get rows that satisfy the first condition, we can use an INNER JOIN
The second condition, we can include those rows in the same SELECT by converting the INNER JOIN to a LEFT OUTER JOIN.
The third condition, we will need a separate SELECT, which can use an anti-join pattern. (We could also use a NOT EXISTS or a NOT IN, but this particular specification is one that anti-join is perfectly suited to.)
We can use a UNION ALL set operation to combine the results from the two SELECT statements.
We'll get the rows first, and then work on the expressions to get the columns
For the first query
SELECT t1.name
FROM table1 t1
LEFT
JOIN table2 t2
ON t2.name = t1.name
For the second query
SELECT a2.name
FROM table2 a2
LEFT
JOIN table1 a1
ON a1.name = a2.name
WHERE a1.name IS NULL
The trick here (the anti-join pattern) is the condition in the WHERE clause, that excludes any rows that found a match. So we are left with rows from a2 that didn't have a matching row in a1.
To use a UNION ALL set operation to combine those, the number of columns and datatypes of the columns have to match. Filling out the expressions in the SELECT lists, and adding an ORDER BY clause, we get something like this:
(not tested)
(
SELECT t1.name
, t1.eyes
, t1.hair
, t2.hand
, t2.foot
FROM table1 t1
LEFT
JOIN table2 t2
ON t2.name = t1.name
)
UNION ALL
(
SELECT a2.name
, a1.eyes
, a1.hair
, a2.hand
, a2.foot
FROM table2 a2
LEFT
JOIN table1 a1
ON a1.name = a2.name
WHERE a1.name IS NULL
)
ORDER BY `name`
Note that to get those ordered, we add parenthesis around each SELECT and follow the last one with an ORDER BY clause.
Again, in MySQL this requires a minimum of two SELECT statements.
There are other query patterns that can return an equivalent result, but those will require more than two SELECT.