How to Review AI-Generated SQL Before You Trust the Number

2026年8月22日2 次浏览来源:Dev.to阅读原文

An AI assistant will write you a query in ten seconds, the query will run, and the number that comes back will look completely reasonable.

This page gives you the five checks that tell you whether that number is right.

They take about two minutes, they need no tools beyond the database you already have, and they catch the four mistakes AI-written SQL actually makes.

The order matters.

The checks are arranged cheapest first, so the first one costs a single row count and the last one costs a short conversation.

Most wrong queries fall to the first two.

The short version.

A query that runs has only passed a grammar check.

The number is right when the rows, the filters and the denominator match the question you asked.

The database only takes a query as far as the first gate.

Why a query that runs can still be wrong Before the list: what do you think the database actually checks when it accepts a query?

Grammar.

That is the whole list.

Spell a table name wrong and you get an error.

Sum the wrong column, join in a way that doubles rows, or filter after grouping when the question needed it before, and you get a clean result set with a wrong number in it.

Every mistake on this page is valid SQL.

AI assistants add one specific difficulty: their queries are fluent.

The aliases are tidy, the formatting is clean, and the shape looks like something a careful person wrote.

Fluency reads as correctness, and it is not the same thing.

Treat an AI query the way you would treat a first draft from a new colleague: with respect, and with the row counts open.

The table the examples run on Everything below runs on one small shop dataset, so every number can be checked by hand.

Thirteen orders in July, five customers, and a table where two orders were refunded in two parts.

Eleven of the thirteen orders are completed; one is refunded, one is pending.

There is also a table listing internal accounts, and it contains one NULL row, because real lookup tables usually do.

The gross value of the eleven completed orders is 1,605.

Total refunds are

275.

Hold on to those two numbers.

Check 1: count the rows before you trust the sum Before the answer: eleven completed orders, five refund rows.

After a LEFT JOIN from orders to refunds, does the query see eleven rows, or more?

Here is the query an assistant wrote for "net revenue from completed orders": It runs.

It returns 1,830.

The right answer is 1,330 , which you already know, because 1,605 minus 275 is 1,330.

The join is the problem.

Two orders were each refunded in two parts, so each of those orders matches two refund rows.

The join turns eleven rows into thirteen, and counts those two orders twice: 2,105 instead of 1,605.

The extra 500 is exactly the value of the two double-counted orders.

This is called fan-out: a join multiplies rows whenever the key on the other side appears more than once.

The check costs two counts: That one comparison decides it.

If the second number grew, the join fanned out and every SUM or AVG over the left table's columns is suspect.

If it held, the join is safe and you move on.

Check 2: look for NULL in every filter The next request was "the same revenue, excluding staff accounts".

The assistant wrote: This returns NULL , from zero rows.

Not a smaller number.

Nothing.

Say out loud why one NULL in could empty the whole result, before reading on.

Here is the mechanism. asks, for each order, "is this customer different from every value in the list?" One of the values in the list is NULL, and SQL cannot say whether anything is different from NULL.

The comparison comes back unknown, unknown is not true, and no row survives.

One NULL row in a lookup table silently empties the result.

The fix is either to keep NULL out of the list, or to use , which does not have this behavior: The reviewer's habit: for every column a filter touches, ask what happens to that filter when the column is NULL.

The same blindness sinks , which is covered in NULL in SQL.

Check 3: ask where the filter sits, W

分享