lesson 5 of 6 · groupby, joins, and first featuresgroupby, joins, and first aggregateslesson 5 of 6 · groupby, joins, and first featuresgroupby, joins, and first aggregateslesson 5 of 6 · groupby, joins, and first featuresgroupby, joins, and first aggregateslesson 5 of 6 · groupby, joins, and first featuresgroupby, joins, and first aggregateslesson 5 of 6 · groupby, joins, and first featuresgroupby, joins, and first aggregateslesson 5 of 6 · groupby, joins, and first featuresgroupby, joins, and first aggregateslesson 5 of 6 · groupby, joins, and first featuresgroupby, joins, and first aggregateslesson 5 of 6 · groupby, joins, and first featuresgroupby, joins, and first aggregateslesson 5 of 6 · groupby, joins, and first featuresgroupby, joins, and first aggregateslesson 5 of 6 · groupby, joins, and first featuresgroupby, joins, and first aggregateslesson 5 of 6 · groupby, joins, and first featuresgroupby, joins, and first aggregates
Checkpoint
One last thing before we move on. pass this to mark the lesson done, or skip and keep moving. hop to the next when you're ready.
Checkpoint. Write left_join(users, features, default): return one row per user (the whole population), attaching that user's features or default when missing — plus a row-count guard that proves the join didn't explode. Print each row, then the guard verdict.