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
The recruiting team tracks one row per application in applications. A decided application has outcome set to 'offer' or 'rejected'. One still working its way through the process has outcome = NULL — nobody has decided yet. offer_amount is filled in only when the outcome is 'offer'.
Return one row per role showing how that role's funnel is going, ordered by role.
Result columns · in this order
role | The role applied for. |
applications | How many applications that role received. |
not_offered | Applications that did not end in an offer, including the ones still undecided. |
offers | How many applications ended in an offer. |
offer_spend | Total value of those offers; 0 for a role that made none. |
How to approach it
Aggregate the whole table in one GROUP BY — no WHERE clause. The only hard part is writing each measure so a NULL lands where it belongs.
Sample input
| application_id | role | applied_on | outcome | offer_amount |
|---|---|---|---|---|
| 1 | Data Engineer | 2026-02-02 | offer | 145000 |
| 2 | Data Engineer | 2026-02-03 | offer | 138000 |
| 3 | Data Engineer | 2026-02-04 | rejected | null |
| 4 | Data Engineer | 2026-02-05 | rejected | null |
| 5 | Data Engineer | 2026-02-06 | null | null |
| 6 | Data Engineer | 2026-02-09 | null | null |
| 7 | Analytics Engineer | 2026-02-02 | offer | 120000 |
| 8 | Analytics Engineer | 2026-02-03 | rejected | null |
| 9 | Analytics Engineer | 2026-02-04 | rejected | null |
| 10 | Analytics Engineer | 2026-02-05 | rejected | null |
| 11 | Analytics Engineer | 2026-02-06 | null | null |
| 12 | Analytics Engineer | 2026-02-10 | null | null |
| 13 | Data Analyst | 2026-02-02 | rejected | null |
| 14 | Data Analyst | 2026-02-03 | rejected | null |
| 15 | Data Analyst | 2026-02-04 | rejected | null |
| 16 | Data Analyst | 2026-02-05 | rejected | null |
| 17 | Data Analyst | 2026-02-06 | null | null |
| 18 | Data Analyst | 2026-02-11 | null | null |
| 19 | ML Engineer | 2026-02-02 | offer | 160000 |
| 20 | ML Engineer | 2026-02-03 | offer | 155000 |
| 21 | ML Engineer | 2026-02-04 | offer | 152000 |
| 22 | ML Engineer | 2026-02-05 | rejected | null |
| 23 | ML Engineer | 2026-02-06 | null | null |
| 24 | ML Engineer | 2026-02-12 | null | null |
| 25 | Data Scientist | 2026-02-02 | offer | 150000 |
| 26 | Data Scientist | 2026-02-03 | rejected | null |
| 27 | Data Scientist | 2026-02-04 | null | null |
| 28 | Data Scientist | 2026-02-05 | null | null |
| 29 | Data Scientist | 2026-02-13 | null | null |
29 rows — scroll inside the table to see them all.
Expected output
| role | applications | not_offered | offers | offer_spend |
|---|---|---|---|---|
| Analytics Engineer | 6 | 5 | 1 | 120000 |
| Data Analyst | 6 | 6 | 0 | 0 |
| Data Engineer | 6 | 4 | 2 | 283000 |
| Data Scientist | 5 | 4 | 1 | 150000 |
| ML Engineer | 6 | 3 | 3 | 467000 |
5 rows — all rows shown.
Constraints
not_offered. Watch what outcome <> 'offer' does to a NULL — the comparison is not true, and it is not false either.applications must count every row for the role, decided or not.offer_spend must be a number for every role. A role that made no offers should report 0, not an empty cell.WHERE clause — every role stays in the result, and every application counts towards its role's total.Worked example
Take Data Engineer. It has 6 applications: 2 offers, 2 rejected, and 2 nobody has decided yet. not_offered is 4 — the 2 rejections plus the 2 undecided.
Write WHERE outcome <> 'offer' and you get 2 instead, because comparing NULL to 'offer' yields NULL rather than true, and only true rows survive a filter.
Use this as your own check: for every role, not_offered + offers must equal applications. If a row does not add up, the undecided rows fell out.
What this tests
Three-valued logic: that a comparison against NULL is unknown rather than false, that COUNT(column) skips NULLs while COUNT(*) does not, and that SUM over a group with no values returns NULL instead of 0.
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.