{"id":"data2-fix-ai-sql-three-bugs-lines","audience":"analysts","category":"data","track":"data","technique":"verification","level":"advanced","title":"Find the three bugs in an AI-written SQL query","free":false,"task":"An AI wrote this query for orders per customer by region, but the numbers look wrong. Write exactly 3 plain-text lines labeled Bug 1:, Bug 2: and Bug 3:, under 100 words, each naming the problem and the fix in the same line. No code block, and don't rewrite the whole query.","materialLabel":"The query and what it should do (attached to your prompt automatically)","material":"Goal: average number of PAID orders per customer, by region, for October 2025, including customers who placed no orders.\n\nAI-written query (Postgres):\n\nSELECT c.region,\n       COUNT(o.order_id) / COUNT(c.customer_id) AS orders_per_customer\nFROM customers c\nJOIN orders o ON o.customer_id = c.customer_id\nWHERE o.order_date >= '2025-10-01'\nGROUP BY c.region;\n\nTables:\ncustomers(customer_id, name, region)\norders(order_id, customer_id, order_date, status, total_cents)\n  status values: 'paid', 'refunded', 'cancelled'\n\nObserved problems:\n- Every region shows 1 or 2, never a decimal, and the number seems high.\n- Customers with no orders in October seem to be missing from the denominator.\n- Some November orders look like they are in the numbers.\n\nExpected shape: region, orders_per_customer (one decimal).","rules":[{"type":"plainText"},{"type":"maxWords","max":100}],"mistakes":[{"title":"Rewriting the whole query","why":"The AI posts a corrected query in a code block.","fix":"Add: \"No code block and no full rewrite; fix in the same line.\"","checks":["r0"]},{"title":"Missing the filter placement","why":"The AI adds status and dates in WHERE, so the LEFT JOIN still drops customers.","fix":"Add: \"Put paid status and the October range in the ON clause.\"","checks":["r1"]},{"title":"Stopping at the join","why":"The AI finds the join bug and misses integer division and the distinct count.","fix":"Add: \"Bug 3: integer division and COUNT(DISTINCT c.customer_id).\"","checks":["r2"]},{"title":"Leaving the format to chance","why":"The AI picks its own length and layout unless told the exact shape.","fix":"Add: \"Plain text, no bold or headings.\"","checks":["plainText"]},{"title":"Trusting the AI to count words","why":"AI is bad at counting. Ask for a total word limit and it often lands over it.","fix":"Cap each part instead, for example \"each line under 15 words.\"","checks":["maxWords"]}],"promptHints":[{"label":"Asks for three labels","patterns":["bug 1:","bug 2:","bug 3:"]},{"label":"Names the join","patterns":["left join"]},{"label":"Names the filters","patterns":["paid","upper","on clause"]},{"label":"Names integer division","patterns":["integer division","distinct"]},{"label":"Rules out code","patterns":["no code block","no full rewrite"]}],"hint":"Debugging prompts work when you ask for a fixed number of bugs in a fixed shape and rule out a full rewrite.","mission":"Why are the numbers in this SQL wrong?","musts":["Three labeled bugs","Fix in each line","No code block"],"rubricLabels":["One line says the plain JOIN drops customers with no orders, and the fix is a LEFT JOIN from customers so zero-order customers stay in the denominator","One line says the filters are wrong: there is no paid-status filter and no upper date bound (so November orders are included), and they should be in the LEFT JOIN's ON clause so zero-order customers are not removed","One line says COUNT / COUNT is integer division and counts rows rather than customers, and the fix is COUNT(DISTINCT c.customer_id) with a decimal (1.0 * or a numeric cast, ROUND to one decimal), and the reply has no code block"]}