Precision: Define the Answer
Concept. Step one: precision. Runs ≠ correct, so before the model writes a line, you pin the precision somewhere: in the prompt, or in the SQL you write yourself. A vague prompt pins nothing, so the model picks one reading of your question and you cannot tell which. The spec decides which query is right.
Intuition. "Users who don't listen to Taylor Swift" is not one question. It has three reasonable readings that return different users, and the model commits to one without telling you which. Reading the result back takes knowing the SQL.
The LLMs and SQL page named three steps. This is the first: precision. The request looks exact, but it can be read more than one way:
"Find the users who don't listen to Taylor Swift."
Figure 1. One question, two valid answers that split on Mickey, Minnie, and Daffy, who each play both Taylor and other artists. The model commits to one and never says which. Blue is the strict reading (just Pluto), orange the broad reading (all four).
The two readings differ on three users. Mickey, Minnie, and Daffy each play Taylor and other artists, so "never played a Taylor song" drops all three while "doesn't listen to only Taylor" keeps them: those three are the gap between the blue answer and the orange one, and Mickey is no different from the other two. Pluto sits in both: he never played Taylor, and he is not a Taylor-only listener either. The English settles none of it; the spec has to.
In the Prompt, or in the SQL
Take the prompt first. Here is the same request written two ways:
Figure 2. A vague prompt (grey) says almost nothing, so the model can write Query A (LEFT JOIN, all four users) or Query B (NOT IN, only Pluto) and you cannot tell which. The precise prompt (blue) numbers what the model must not guess: engine, schema and join paths, definition, edge case, and a show-your-work trace. Its [Definitions] line fixes Query B and {Pluto}.
Every numbered line blocks a guess the model would otherwise make. Drop one and you hand it room to hallucinate. That keeps the prompt minimal and sufficient, not merely long:
[Engine]pins the SQL dialect (!=vs<>, NULL and string behavior). Unspecified, the model picks one.[Schema]gives exact table and column names so it cannot invent one. The join paths matter most: the key is often implicit, and the model will assume a foreign key or join on the wrong column. WritingON Listens.user_id = Users.user_idremoves that guess.[Definitions]is the actual ask, the one line only you can supply.[Edge cases]keep the no-listen user (Pluto), whom a careless query silently drops.[Show your work]forces the step-by-step trace you check the result against.
Figure 3. Two readings is the easy case. Each independent ambiguity is a fork: inner vs LEFT JOIN, whether a NULL counts, rows vs DISTINCT. k binary forks make 2^k queries that all run, and a fork with more than two options (a join can be inner, left, right, or full) makes even more, so 2^k is the floor. The spec traces the one blue path to the query you meant; with no spec, the model picks a leaf for you.
Resolving those forks is the whole of precision. There are three ways to do it, and they all reach the same query:
Figure 4. Three routes to the same query. Push writes every fork into an English spec. Pull lets the model interview you, one clarifying question per fork. Write SQL skips the prose, since every fork is already a syntactic choice (LEFT JOIN vs JOIN, COUNT(*) vs COUNT(DISTINCT)). The English routes only reconstruct what the SQL states outright, so the spec is the price of staying in English.
What you cannot do is leave the forks open. A vague prompt does not erase them, it just hands every fork to the model to resolve silently. Something collapses that tree to one query no matter what. Your only choice is whether that something is you, in SQL or in English, or the model guessing alone.
For this request, that one decision is Query B over Query A. State it in the prompt, draw it out through the model's questions, or just write Query B. The answer comes from you. The model still has to turn it into SQL that runs, which is the next step.
Takeaways
-
A vague prompt picks for you. One phrase, several queries that disagree, and the model chooses one silently.
-
Precision lives in the prompt or the SQL. Push it into an English spec, let the model interview you, or just write the query, which is precise by construction.
-
Define the answer before the model writes. Running the SQL and proving the result come next.
Next
Execution: Run It on Real Data → You defined the spec, Query B. Second step: execution. The model writes the SQL and iterates against a real database until it works.