Technical skill practice
SQL LEFT JOIN: Keep Unmatched Rows When Filtering
A LEFT JOIN keeps every row from the left input and adds matching right-side values. Unmatched right-side columns become NULL. The placement of a right-side filter can determine whether unmatched left rows survive.
The practice task
List every study group and its approved room reservation, including groups that have no approved reservation. One group has a pending reservation; it should still appear with no approved room.
The data below is fictional. Run the example in a new SQLite database. It was checked with SQLite 3.51.0; other databases may use different syntax, functions or type rules.
Complete worked query
Create the small fixture and run the query together. The IDs, boundary values and missing entries make the result small enough to check by hand.
CREATE TABLE study_groups(id INTEGER, name TEXT);
CREATE TABLE reservations(group_id INTEGER, room TEXT, status TEXT);
INSERT INTO study_groups VALUES (1,'Algebra'),(2,'Biology'),(3,'Chemistry');
INSERT INTO reservations VALUES (1,'R1','approved'),(2,'R2','pending');
SELECT g.name, r.room
FROM study_groups AS g
LEFT JOIN reservations AS r
ON r.group_id = g.id AND r.status = 'approved'
ORDER BY g.name;Checked result
This is the result of the exact example above. NULL marks a missing database value rather than the text string "NULL".
Result rows
name | room
Algebra | R1
Biology | NULL
Chemistry | NULL
Read the result
The join condition limits which reservations qualify as matches. Algebra has an approved room. Biology has a reservation, but it does not qualify; Chemistry has none. Both groups remain because study_groups is the preserved input.
Moving r.status = 'approved' to WHERE would remove the NULL-extended rows and therefore remove Biology and Chemistry. That would answer a different question: which groups currently have approved reservations?
The query also assumes that multiple approved reservations should produce multiple rows. If the intended report requires one reservation per group, define a choice rule such as a particular date or reservation ID. Do not choose an arbitrary room with an aggregate just to force one row.
Mistakes to check
Use these checks when adapting the example to a different dataset.
- Keep match qualification in ON when unmatched left rows must remain.
- Use an explicitly non-null right-side key for unmatched-row checks.
- A left join can still multiply rows when several matches qualify.
Questions, answered
Can I run this example as written?
Yes, in a new SQLite database using the schema and values shown. The result above was checked with SQLite 3.51.0. Keep it separate from an existing database.
Why does adding OR r.status IS NULL in WHERE not always fix a misplaced filter?
A pending reservation can match the join before the WHERE filter runs. That matched row is not replaced with a new NULL row when the filter rejects it. Restrict the match in ON instead.
Sources and examples
ResumizeAI team. Examples are fictional teaching material, not customer results. Replace sample details with your own facts.
Your experience. A complete resume.
Build in Resumize with ATS-friendly templates, guided editing and a live preview. Start free, then upgrade when you need more.
Free account required. Free-plan PDF exports include a watermark.