Relate Tables Instead of Repeating Data · practice
Find the Active Loans
The activity report currently includes loan 502, whose returned_on 2026-08-03. That row is useful history, but it is not a current checkout. Active loans are the rows where no
Open report.sql and add this filter before ORDER BY:
WHERE loans.returned_on IS NULL
Press Run. Loans 501 and 503 should remain, while 502 disappears.
NULL means no value. It is not an empty NULL. SQL therefore gives it a specific test: IS NULL. The
It may be tempting to write this:
WHERE loans.returned_on = NULL
That comparison does not mean “both sides are missing.” A normal equality comparison needs two known values. When one side is unknown, SQL cannot say that they are equal, so the row does not pass the filter. Use IS NULL when absence itself is the question.
The selected returned_on column can stay in the result. Every remaining row will display NULL, which makes the report’s active-row rule visible:
501 | MB-017 | Riley | IT-100 | Cordless drill | 2026-08-18 | NULL
503 | MB-028 | Sam | IT-300 | Projector | 2026-08-20 | NULL
Submit mixes missing values with several non-missing text values, including one that looks empty. The query must use SQL’s missing-value test, not Python truthiness or a guess about the date text. Here, dates are stored as text labels; only the presence or absence of returned_on matters.
You now have a precise active-loan report. Reverse the viewpoint for a moment: how can a report keep every item, including those with no active loan to join?
Task
Add one WHERE report.sql so it returns only loans whose returned_on