How to check an AI-written SQL query before you send the number
On this page · 9
Ask an assistant for September's average order value on Meridian, a fictional practice marketplace, and a reply like the query below is plausible. It runs and says €76.84. Here is what its join does to two orders:
| order_id | product line | items_total_eur |
|---|---|---|
| O000421 | 1 of 1 | €28.03 |
| O000424 | 1 of 3 | €119.61 |
| O000424 | 2 of 3 | €119.61 |
| O000424 | 3 of 3 | €119.61 |
The average of these four rows is €96.72. The average of the two orders is €73.82. Over all September orders the right figure is €61.08: each order counted once, cancelled orders left out.
-- an assistant-style query; we wrote it to show the trap
SELECT
ROUND(AVG(o.items_total_eur), 2) AS avg_order_value,
ROUND(COUNT(*) * 1.0 / COUNT(DISTINCT o.order_id), 2) AS products_per_order
FROM meridian.orders AS o
JOIN meridian.order_items AS i ON i.order_id = o.order_id
WHERE o.created_at >= DATE '2026-09-01';
-- result: 76.84 · 1.79
Nothing errored. Four checks would have stopped it, and none of them needs more SQL than the query itself.
Check 1: say what one row is
After FROM orders JOIN order_items, one row is one product line, not one order. AVG(o.items_total_eur) therefore averages lines: an order with three products is counted three times. Orders with more products are usually bigger, so the average goes up.
Ask two questions of any query: what is one row after the last join? and is the number I'm reporting per that thing? Here the answers are "a product line" and "no, per order", so the query can't be right as written.
Check 2: count the rows at every step
SELECT COUNT(*)
FROM meridian.orders
WHERE created_at >= DATE '2026-09-01';
-- result: 8,905
SELECT COUNT(*)
FROM meridian.orders AS o
JOIN meridian.order_items AS i ON i.order_id = o.order_id
WHERE o.created_at >= DATE '2026-09-01';
-- result: 15,953
8,905 orders became 15,953 rows. Once the row count goes up, any SUM or AVG of an order-level column is suspect. The second column of the assistant's query is the exception: products per order is lines divided by orders on purpose, so its 1.79 means what it says. Half the query being right is exactly why the wrong half is easy to miss.
Check 3: get the number a second, simpler way
SELECT ROUND(AVG(items_total_eur), 2)
FROM meridian.orders
WHERE created_at >= DATE '2026-09-01';
-- result: 61.16
€61.16 against €76.84. Two queries for the same thing that disagree by a quarter count different things, and the simpler one, with no join, is usually the one to trust. If you can't write the simpler query yourself, ask the assistant for it and compare. Don't ask it whether the first one was right.
Check 4: compare the filters with the request
The query answers a slightly different question than the one asked. Three things to check against the request:
- Status. The query keeps 239 cancelled orders. Paid orders only: €61.08 over 8,666 orders.
- Period. The practice data ends on 22 September, so "September" here is 22 days. Say so next to the number.
- Which money.
items_total_euris the basket before the platform discount;paid_euris after it. On paid September orders that is €61.08 or €58.41. Ask which one the person means.
SELECT ROUND(AVG(items_total_eur), 2), ROUND(AVG(paid_eur), 2), COUNT(*)
FROM meridian.orders
WHERE status = 'paid' AND created_at >= DATE '2026-09-01';
-- result: 61.08 · 58.41 · 8,666
Try it on the assistant's answer
Try it · 30 seconds · from Atterna’s practice
“The average order value in September is €76.84, with 1.79 products per order.”
SELECT ROUND(AVG(o.items_total_eur), 2) AS avg_order_value, ROUND(COUNT(*) * 1.0 / COUNT(DISTINCT o.order_id), 2) AS products_per_order FROM orders o JOIN order_items i ON i.order_id = o.order_id WHERE o.created_at >= DATE '2026-09-01';
Before you forward €76.84, which check tells you the most, fastest?
Preparing the practice…
What to send
Average order value, paid orders, 1–22 September (the data ends on the 22nd), basket before discount: €61.08 over 8,666 orders.
That sentence is the four checks made visible: what was counted, which rows, which period, which money. It takes ten more seconds than "€76.84", and nobody has to come back and ask. Be sure of the number before you say it.
Let the assistant write the checks, not judge them
Assistants are useful for writing the row-count queries and the simpler second query. They are less reliable at judging their own answer, because they tend to explain the query they already wrote. Run the checks on the data and read the results yourself. Six AI SQL mistakes that run without an error lists the patterns to look for, and the seven-question checklist works when you only have the number and no SQL. In our small test of 12 questions, the model avoided this particular join and its misses were about meaning, not syntax. Other models and prompts do make it, and the checks cost a minute.
Check a number without writing SQL
If you work with numbers in Excel, BI or AI answers, Wrong Number is the three-minute version of this check: one database, three colleagues, three different right answers, and no code. Play Wrong Number. When you have a real answer from an assistant, paste it into the AI answer checker. Its rules look for a SUM or AVG after a join, a missing status filter and other patterns from this page.
FAQ
Can I trust SQL written by ChatGPT or another AI assistant?
Trust it as a draft. Assistant-written SQL usually runs, and that is the risk: the mistakes that matter (a join that repeats rows, a missing filter, the wrong denominator) produce a plausible number and no error. Check what one row is, count rows before and after each join, and compare with a simpler query before you use the result.
What is the fastest way to check an AI's SQL query?
Count the rows before and after every join. If the row count goes up, a sum of a column from the first table is inflated, and an average is weighted by how many rows each order matched, so it can move either way. On the Meridian example, 8,905 orders became 15,953 rows and the average order rose from €61.16 to €76.84.
Do I need to know SQL to check an AI-written query?
Enough to read FROM, JOIN, WHERE and GROUP BY, and to run a COUNT(*). You don't need to write complex queries: most checks are row counts and one simpler query that you can ask the assistant to write and then run yourself.
Should I ask the AI to check its own query?
Ask it to write check queries, then run them on the data yourself. Asking "are you sure?" mostly gets the same query explained again. The evidence is in the row counts and in a second calculation, not in the chat.
Practise this, free
A free account opens hands-on lessons on a realistic marketplace.
- All 10 days of the SQL courseFrom your first table to JOINs and window functions
- Meridian episode 1A full analyst week: the record that wasn’t
- Your first portfolio projectFinished work as a ready GitHub project, with your SQL and charts
- Progress on any deviceYour cheat sheet and review cards go with you
Examples use Meridian, Atterna’s fictional practice marketplace.