Say I have a table C that references rows from tables A and B:
id, a_id, b_id, ...
and a simple query:
SELECT * FROM C WHERE a_id=X AND b_id=Y
I would like to differentiate between the following cases:
- No row exists in A where id = X
- No row exists in B where id = Y
- Both such rows in A and B exist, but no rows in C exist where a_id = X and b_id = Y
The above query will return empty result in all those cases.
In case of one parent table I could do a LEFT JOIN
like:
SELECT * FROM A LEFT JOIN C ON a.id = c.a_id WHERE c.a_id = X
and then check if the result is empty (no row in A exists), has one row with NULL c.id
(row in A exists, but no rows in C exist) or 1+ rows with non-NULL c.id
(row in A exists and at least one row in C exists). A bit messy but it works, but I was wondering if there is a better way of doing this, especially if there is more than one parent table?
Best Answer
I think I managed to get a satisfactory solution using the following two features:
Subselect bound to a column, which allows me to check if a row exists and (importantly) get a NULL value otherwise (e.g.
SELECT (SELECT id FROM a WHERE id = 1) as a_id)
)Common Table Expressions
Initial data:
And the query:
This query will always return at least one row. In case if both parent table ids are valid and there are some records, I get
If either
person_id
orthing_type_id
are invalid, I get one row wherename
is NULL and eitherperson_id
orthing_type_id
is NULL:If both
person_id
andthing_type_id
are valid but there are no records inthings
, I get one row where bothperson_id
andthing_type_id
are not NULL, but thename
is NULL:Since I have a
NOT NULL
constraint onthings.name
, I know that this case can only mean that there are no matching records inthings
.