The twisttwist, I think, is this: the Venn diagram is the right tool to visualize your objective, but the SQL JOIN
is the wrong approach. You need a UNION
(or equivalent) at the core of your query.
SELECT organization FROM admin_organization WHERE user = 10
UNION
SELECT organization FROM moderator_organization WHERE user = 10
SELECT organization FROM admin_organization WHERE user = 10
UNION
SELECT organization FROM moderator_organization WHERE user = 10
SELECT *
FROM (
SELECT organization AS id FROM admin_organization WHERE user = 10
UNION
SELECT organization FROM moderator_organization WHERE user = 10
) x
JOIN organization USING (id);
SELECT *
FROM (
SELECT organization AS id FROM admin_organization WHERE user = 10
UNION
SELECT organization FROM moderator_organization WHERE user = 10
) x
JOIN organization USING (id);
It's typically (substantially) cheaper to apply UNION
on just the ID column, and then join. It may even be a necessity, if some of the columns have types have data types with no equality operator. More common than one might think. See:
AssumingWhile referential integrity, is enforced with FK constraints, nothing is lost in the join.
For convenience, itI added a column alias in the subquery (organization AS id
), so that we can use the simplifiedsimple join condition with USING (id)
which, in turn, allows us to use the simple (and now correct) SELECT *
in the outer query to get all columns of the table organization
without a duplicate ID columncolumns.
SELECT *
FROM organization o
WHERE EXISTS (SELECT FROM admin_organization WHERE user = 10 AND organization = o.id)
OR EXISTS (SELECT FROM moderator_organization WHERE user = 10 AND organization = o.id);
SELECT *
FROM organization o
WHERE EXISTS (SELECT FROM admin_organization WHERE user = 10 AND organization = o.id)
OR EXISTS (SELECT FROM moderator_organization WHERE user = 10 AND organization = o.id);
A naming convention with descriptive names can avoid some of the confusion and noise. Use organization_id
the column name "organization_id" (or org_id
"org_id" if you prefer short names and there is no ambiguity) for all three: admin_organization.organization
, moderator_organization.organization
, and organization.id
.