Streamhub's billing team processes charges on sessions that have completed (and therefore have a recorded end time).
Write a query to return the ID, user ID, and start time of every session that has ended.
Assumptions:
- The
sessionstable contains every session ever recorded on the Streamhub platform. - The
ended_atcolumn records when each session closed; sessions still in progress haveended_atset toNULLand should be excluded. - The
user_idcolumn links each session to the user who initiated it.
Output:
- One row per completed session, with columns
id,user_id, andstarted_at.
Schema · analytics 5 tables
Run previews · Check grades
Write a query, then run it to see results here.
Worked solution Try it yourself first
SELECT
id,
user_id,
started_at
FROM
sessions
WHERE
ended_at IS NOT NULL The shape
"Completed" is encoded as the presence of an end time, not a boolean flag. The billing run needs every session whose ended_at has been recorded, so IS NOT NULL on that column is the completed-session filter.
Clause by clause
SELECT id, user_id, started_atreturns the three columns billing needs: which session, which user to charge, and when the session began.FROM sessionsreads the session log. The same table that holds open sessions (withended_atasNULL) holds the closed ones too; the difference is only in the value of that one column.WHERE ended_at IS NOT NULLkeeps only rows where the end timestamp is present.IS NOT NULLreturnstruefor completed sessions andfalsefor in-progress ones.
Why this and not a boolean is_complete flag
Some schemas track completion with a boolean column. This one uses the NULL-ness of ended_at as the same signal, and it's tighter: a single column holds both the status (open or closed) and the data (when it closed). A boolean flag plus an end-timestamp column would let the two drift out of sync: is_complete = true with ended_at = NULL, or vice versa. With this shape, the truth lives in one place.
The trap
Billing on WHERE ended_at <> NULL would return zero rows and charge no one, even though dozens of sessions completed. <> against NULL evaluates to unknown, never true, so the filter passes nothing. The query runs without error, the billing report comes back empty, and revenue silently disappears. Any operator that compares to NULL (=, <>, <, >) produces unknown. IS NOT NULL is the only correct test for presence.
You practiced using IS NOT NULL to scope a query to records that have reached a particular state. End-timestamp-not-null is the everyday shape for 'completed only' filters.