{"id":"code-work-pm-sql-ab-test-conversion","audience":"product-managers","category":"coding","track":"coding","technique":"context","title":"Compare A/B conversion, dropping users who saw both","free":false,"task":"Write one SQL query for the checkout_v2 experiment that returns one row per variant with users, converted and conversion_pct (rounded to 1 decimal, no integer division). Leave out users who were exposed to both variants. A user converts only with a purchase within 7 days after their first exposure, measured from first_seen. One code block, at most 32 lines, then under 25 words outside the code.","materialLabel":"Schema and sample rows (attached to your prompt automatically)","material":"EXPERIMENT DATA - Pinecrest Shop (Postgres)\n\nexposures: user_id, experiment, variant ('control' or 'treatment'), seen_at\npurchases: user_id, order_id, purchased_at, total\n\nSample exposures (experiment = 'checkout_v2'):\n41 | control | 2026-10-02 10:00\n41 | control | 2026-10-04 18:30\n52 | treatment | 2026-10-03 09:15\n63 | control | 2026-10-03 11:00\n63 | treatment | 2026-10-05 12:40\n\nSample purchases:\n41 | 9001 | 2026-10-06 12:00 | 54.00\n52 | 9002 | 2026-10-15 08:00 | 22.50\n63 | 9003 | 2026-10-05 13:00 | 80.00\n\nNotes:\n- The test ran from Oct 1 to Oct 21.\n- Purchases include gift cards.\n- Another experiment, nav_redesign, is running at the same time.","rules":[{"type":"codeBlocks","count":1},{"type":"maxCodeLines","max":32},{"type":"maxProseWords","max":25}],"mistakes":[{"title":"Not mentioning double exposure","why":"The AI counts users who saw both versions in both groups, which muddies the result.","fix":"Add: \"Drop users exposed to both variants.\"","checks":["r0"]},{"title":"Leaving \"converted\" vague","why":"The AI counts any purchase ever, even before the user saw the test.","fix":"Add: \"A purchase within 7 days after first exposure.\"","checks":["r1"]},{"title":"Trusting integer division","why":"Dividing two counts can round down to 0 in SQL.","fix":"Add: \"Multiply by 100.0, round to 1 decimal, one row per variant.\"","checks":["r2"]},{"title":"Getting a menu of options","why":"The AI likes to offer two or three versions of the query, so you're left to pick and test them yourself.","fix":"Add: \"Give one query only, in one code block, no alternatives.\"","checks":["codeBlocks","maxCodeLines"]},{"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 12 words. Nothing else.\"","checks":["maxProseWords"]}],"promptHints":[{"label":"Drops double-bucketed users","patterns":["both variants","both groups","exposed to both","count\\(distinct variant"]},{"label":"Defines conversion","patterns":["7 days","first exposure","first_seen","within"]},{"label":"Names the experiment","patterns":["checkout_v2"]},{"label":"Handles the percent","patterns":["100\\.0","integer division","round"]},{"label":"Asks for one answer only","patterns":["\\b(one|single|1)\\s+(query|code block|block|version)","only one","no (alternatives|options|other versions)"]}],"hint":"Look at user 63. Tell the AI what to do with people like that, and exactly what counts as a conversion.","rubricLabels":["Keeps only experiment = 'checkout_v2' and drops users exposed to both variants (for example HAVING COUNT(DISTINCT variant) = 1), so user 63 is left out","Uses each user's first exposure (MIN(seen_at)) and counts a conversion only for a purchase from that time up to 7 days after it","Returns one row per variant with users, converted and conversion_pct, where conversion_pct uses 100.0 (or a numeric cast) and is rounded to 1 decimal"]}