Reputation: 45
I'm trying to display the total number of rows in a full outer join table. I have the following code, but mysql says there is an error with duplicate columns. The 2 tables, actors and directors, have the same columns as they are supposed to provide similar information in their respective categories.
SELECT COUNT(*) FROM
(SELECT * FROM directors LEFT OUTER JOIN actors
ON directors.name = actors.name
UNION
SELECT * FROM directors RIGHT OUTER JOIN actors
ON directors.name = actors.name) AS table1;
What can be done to fix the code so it will run properly? FYI, the code from within the parenthesis runs fine. The problem only arises once I put in the SELECT COUNT(*) clause.
Upvotes: 1
Views: 4092
Reputation: 1269803
I'm not sure what you are getting at with the full join
. But the best way to implement it in MySQL uses two left join
s and a union
:
select count(*)
from ((select name from directors) union -- on purpose
(select name from actors)
) da left join
directors d
on da.name = d.name left join
actors a
on da.name = a.name;
If I had to guess, though, you just want the number of distinct names between the two tables. If so:
select count(*)
from ((select name from directors) union -- on purpose
(select name from actors)
) da
Upvotes: 0
Reputation: 15951
It might be better to change the right join portion non-redundant, and just add separate counts.
Generic version:
SELECT (SELECT COUNT(*) FROM A LEFT JOIN B ON A.x = B.x)
+ (SELECT COUNT(*) FROM B LEFT JOIN A ON B.x = A.x WHERE A.x IS NULL)
AS outerJoinSize
;
Note: I changed the RIGHT JOIN to a LEFT JOIN and swapped the tables around; in my experience, RIGHT JOIN just tends to make queries a little harder to read (especially when multiple joins are involved).
An completely different alternative...
SELECT
( SELECT SUM(dc1.c * IFNULL(ac1.c, 1)) AS jc
FROM (SELECT name, COUNT(*) AS c FROM directors GROUP BY name) AS dc1
LEFT JOIN (SELECT name, COUNT(*) AS c FROM actors GROUP BY name) AS ac1
ON dc1.name = ac1.name)
+ (SELECT SUM(IF(dc2.name IS NULL, ac2.c, 0)) AS jc
FROM (SELECT name, COUNT(*) AS c FROM actors GROUP BY name) AS ac2
LEFT JOIN (SELECT name, COUNT(*) AS c FROM directors GROUP BY name) AS dc2
ON ac2.name = dc2.name)
...this one figures out how many matches based on the joining field (3 instances of "Bob" in directors and 2 in actors means 6 join results for that name).
Upvotes: 0
Reputation: 46219
Becuase there are two name
columns one is from directors
table, another is from actors
table, and you select *
that will let DB engine confuse which name did you want to get.
if you only want to count
total number you can try this.
SELECT COUNT(*) FROM
(
SELECT directors.name FROM directors LEFT OUTER JOIN actors
ON directors.name = actors.name
UNION
SELECT directors.name FROM directors RIGHT OUTER JOIN actors
ON directors.name = actors.name
) table1;
NOTE
I would suggest use select
clear the columns and avoid using select *
Upvotes: 1