Sign in to run and submit your work
Reading is open to everyone. Running code and saving drafts need an account so your work is yours and comes back on your next visit.
or
CODE WORKSPACE
Before the nightly merge runs against the device table, the platform team wants to see what it would do. roku_devices_staging is today's full extract and roku_devices_target is the warehouse table as it stands. A device missing from the extract has been retired.
Return one row per device, ordered by device_id.
Result columns · in this order
device_id | The device, from whichever side it exists on. |
change_type | insert, update, unchanged or delete. |
How to approach it
Two problems hide here: which rows the join can see, and what <> does when a column is NULL.
Sample input
| device_id | firmware | region | last_seen_on |
|---|---|---|---|
| d01 | 12.6.0 | US | 2026-03-04 |
| d02 | 12.5.1 | null | 2026-03-01 |
| d03 | 12.4.0 | GB | 2026-02-27 |
| d04 | 12.5.1 | DE | 2026-03-02 |
| d05 | 12.3.9 | null | 2026-02-20 |
| d07 | 12.4.0 | CA | 2026-03-04 |
| d09 | 12.6.0 | AU | 2026-03-04 |
| d10 | 12.6.0 | null | 2026-03-04 |
| d11 | 12.4.0 | null | 2026-02-25 |
| d13 | 12.6.0 | JP | 2026-03-04 |
10 rows — all rows shown.
| device_id | firmware | region | last_seen_on |
|---|---|---|---|
| d01 | 12.5.1 | US | 2026-03-01 |
| d02 | 12.5.1 | null | 2026-03-01 |
| d03 | 12.4.0 | GB | 2026-02-27 |
| d04 | 12.5.1 | null | 2026-03-02 |
| d05 | 12.3.9 | IN | 2026-02-20 |
| d06 | 12.5.1 | US | 2026-03-02 |
| d07 | 12.4.0 | CA | 2026-03-01 |
| d08 | 12.5.1 | US | 2026-03-03 |
| d11 | 12.4.0 | null | 2026-02-25 |
| d12 | 12.3.9 | BR | 2026-02-18 |
10 rows — all rows shown.
Expected output
| device_id | change_type |
|---|---|
| d01 | update |
| d02 | unchanged |
| d03 | unchanged |
| d04 | update |
| d05 | update |
| d06 | delete |
| d07 | update |
| d08 | delete |
| d09 | insert |
| d10 | insert |
| d11 | unchanged |
| d12 | delete |
| d13 | insert |
13 rows — scroll inside the table to see them all.
Constraints
change_type is exactly one of 'insert', 'update', 'unchanged' or 'delete'.region or last_seen_on differs.region is nullable on both sides. Two NULLs are the same value for this purpose, and NULL against a value is a change.device_id.Worked example
Device d04 has region NULL in the target and 'DE' in staging: a real update. Device d02 has NULL on both sides: unchanged.
Write the comparison as s.region <> t.region and SQL answers unknown for both, because any comparison involving NULL is unknown rather than true or false. The CASE falls through to 'unchanged', and d04 and d05 are reported as needing no work. The merge then leaves stale regions in the warehouse and nothing in the output says so.
What this tests
NULL-safe comparison and set completeness together: <> cannot detect a change involving NULL, and a LEFT JOIN cannot see rows that exist only in the target.
Submit for review to find out what your query gets right, what it gets wrong, and how it compares with the best working query for this exercise.
This scenario runs a full workspace — editor, canvas and results side by side. It needs a laptop or desktop to be usable. Open this page on a bigger screen to start building.