{"id":"code-work-pm-sql-review-inner-join-bug","audience":"product-managers","category":"coding","track":"coding","technique":"verification","title":"Catch the join bug in a churn query before it ships","free":false,"task":"An analyst's query claims to show the share of September signups that never created a project, but it can only return 0%. Write exactly 2 numbered lines labeled Problem: and Effect:, each under 20 words, then put only the corrected FROM/JOIN line in one code block. Keep the rest of the query unchanged. Under 50 words outside the code.","materialLabel":"The query and its result (attached to your prompt automatically)","material":"Query from Dev (analyst), for the Q4 planning doc:\n\nSELECT\n  ROUND(100.0 * COUNT(*) FILTER (WHERE p.id IS NULL) / COUNT(DISTINCT u.id), 1) AS pct_no_project\nFROM users u JOIN projects p ON p.owner_id = u.id\nWHERE u.signup_at >= '2026-09-01' AND u.signup_at < '2026-10-01';\n\nResult: pct_no_project = 0.0\n\nDev's note: \"Looks like everyone who signs up makes a project! Great news for onboarding.\"\n\nSchema:\nusers: id, email, signup_at\nprojects: id, owner_id, created_at, archived\n\nOther notes:\n- About 4,100 users signed up in September.\n- The onboarding team guessed around 35% never make a project.\n- Archived projects still count as created.","rules":[{"type":"numberedItems","count":2},{"type":"codeBlocks","count":1},{"type":"maxProseWords","max":50}],"mistakes":[{"title":"Rewriting everything","why":"The AI hands back a whole new query, which Dev has to diff line by line.","fix":"Add: \"Only the corrected FROM/JOIN line in the code block.\"","checks":["codeBlocks","r2"]},{"title":"Not asking for the cause","why":"The AI fixes it silently or writes paragraphs on join types.","fix":"Add: \"2 numbered lines labeled Problem: and Effect:, under 20 words each.\"","checks":["numberedItems","r0"]},{"title":"Letting the claim stand","why":"The AI may repeat Dev's conclusion without saying the 0% is impossible.","fix":"Add: \"Say what the 0% result really means.\"","checks":["r1"]},{"title":"Getting a tutorial","why":"By default the AI explains every part of the code at length, which you then have to scroll past.","fix":"Add: \"After the code, one line under 20 words. Nothing else.\"","checks":["maxProseWords"]}],"promptHints":[{"label":"Asks for the cause","patterns":["problem:","why","cause"]},{"label":"Asks about the result","patterns":["effect:","0%","what (the|it) means"]},{"label":"Limits the fix to one line","patterns":["only the (corrected )?(from|join)","one line","rest unchanged|keep the rest"]},{"label":"Sets the shape","patterns":["(2|two) (numbered )?lines","numbered","labeled"]}],"hint":"Ask for the smallest fix and a short reason, so Dev sees exactly what changed and why the 0% can't be true.","rubricLabels":["The Problem: line says the inner JOIN drops users who have no projects, so p.id can never be NULL","The Effect: line says the 0% result is wrong and the real share of users without a project is hidden (not that everyone makes a project)","The code block holds only the corrected line using LEFT JOIN: FROM users u LEFT JOIN projects p ON p.owner_id = u.id"]}