Skip to content
Advertisement

How to differentiate between no rows and foreign key reference not existing?

My users table contains Alice, Bob and Charles. Alice and Bob have a 3 and 2 fruits respectively. Charles has none. A relationship is established using a foreign key constraint foreign key (user_id) references users (id) and a unique (user_id, name) constraint, allowing zero or one fruit per user.

Charles does not have an orange, so there is no resulting row (first query below). However, running the same query for a user that does not exist (second query below) also returns no result.

Is it possible to perform a single query whilst simultaneously differentiating between the user not existing vs the user existing and not having a fruit?

If so, can this also be done to find all the fruits belonging to a particular user (i.e. select * from fruits where user_id = 3 vs select * from fruits where user_id = 99.

Advertisement

Answer

Use a LEFT [OUTER] JOIN:

If the user exists, you always get a row.
If the user has no fruit (of that name), fruit defaults to NULL – which is otherwise impossible since fruit.name is defined NOT NULL.

To get an empty string instead, throw in COALESCE(). But no fruit can be named '' then or it’ll be ambiguous again. Add a CHECK constraint to be sure.

Related:

Aside 1: “name” is not a good name.
Aside 2: Typically, this would be a many-to-many design with three tables: “users”, “fruits” and “user_fruits”. See:

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement