AI as Your Query Copilot
Expert · 18 min read · ▶ live playground · ✦ checkpoint
AI can help you write SQL faster, but it cannot become the person who understands the answer. Treat it as a copilot: useful for drafts, explanations, translations, and names — dangerous when you let confident text outrank your schema and your checks.
Recent text-to-SQL benchmark results make the practical point bluntly: text-to-SQL — asking a model to turn ordinary language into SQL — looks strong on toy benchmarks such as Spider 1.0, which are saturated above 90%, while enterprise-scale schemas such as Spider 2.0 drop frontier models to around 20%. The practical lesson is not "AI is useless." It is "AI makes writing easier and reading more important." You still decide whether the query matches the business question.
What AI is good at
An AI copilot is a language model used as a helper beside your editor. It is strong at turning a half-formed intent into a first draft. It can explain an error message in calmer words. It can translate dialect accents, such as turning a DuckDB QUALIFY pattern into PostgreSQL's compute-first/filter-later CTE shape. It can propose names for columns, aliases, CTEs, and views so your query reads like a small report instead of a pile of expressions.
The best use is not "write my query." It is "help me get to a query I can defend." Give it the schema, the report sentence, and the grain. Ask for one query, not a lecture. Then run the SQL yourself.
Translation help works the same way. A dialect translation is a rewrite from one engine's accent to another, such as SQL Server row limiting to PostgreSQL row limiting, or DuckDB-friendly analytics sugar to the portable CTE pattern you learned in Section 7. Ask the model to name the uncertain parts instead of pretending the rewrite is automatic. Naming help is even safer: good aliases and CTE names make review cheaper, and bad names usually fail in human eyes before they reach production.
Here is a static transcript. No live AI is running in this lesson.
Developer:
Using this PostgreSQL schema, draft a query for total order amount by customer.
customers(id, name, city)
orders(id, customer_id, product, amount)
Return customer name, city, order count, and total amount. Use table aliases.
AI response:
SELECT c.name AS customer_name,
c.city,
count(o.id) AS orders,
sum(o.amount) AS total_amount
FROM customers c
JOIN orders o
ON o.customer_id = c.id
GROUP BY c.name, c.city
ORDER BY total_amount DESC, customer_name;That answer looks reasonable because it names the output grain: one row per customer with orders. Looking reasonable is not enough. The exact SQL from that transcript still gets checked against the real cafe dataset:
SELECT c.name AS customer_name,
c.city,
count(o.id) AS orders,
sum(o.amount) AS total_amount
FROM customers c
JOIN orders o
ON o.customer_id = c.id
GROUP BY c.name, c.city
ORDER BY total_amount DESC, customer_name; customer_name | city | orders | total_amount
---------------+--------+--------+--------------
Ada | Berlin | 2 | 312.00
Linus | Berlin | 2 | 228.00
Edsger | Lisbon | 2 | 105.00
Grace | Lisbon | 1 | 45.00
(4 rows)That is the healthy loop: prompt, draft, inspect, run, read the grid. The model did the typing. You did the accountability.
Where it fails
AI does not know your database unless you give it context, and even then it may invent. A schema hallucination is when the model references a table or column that sounds plausible but does not exist. A wrong join is worse: the columns exist, the query runs, and the join answers a different question. Confident nonsense is the tone problem around both failures — the model can sound certain while being wrong.
This failing answer is intentionally wrong. It guesses that orders has a column named customer. The real schema uses customer_id.
SELECT c.name AS customer_name,
sum(o.amount) AS total_amount
FROM customers c
JOIN orders o
ON o.customer = c.id
GROUP BY c.name
ORDER BY total_amount DESC;ERROR: column o.customer does not exist
LINE 5: ON o.customer = c.id
^
HINT: Perhaps you meant to reference the column "o.customer_id".This is the friendly failure mode because PostgreSQL refuses the query. The scarier version is a subtly wrong join key that exists. Imagine a table with both customer_id and referrer_customer_id; joining on the wrong one might return a tidy grid with a believable row count. That is why 21.3 owns the full verification ritual. For now, learn the stance: AI is allowed to draft, but the schema and the result grid get the final vote.
AI is also useful after the failure, as long as you keep the conversation anchored to real evidence:
Developer:
PostgreSQL returned:
ERROR: column o.customer does not exist
LINE 5: ON o.customer = c.id
^
The schema bar shows orders(id, customer_id, product, amount). What should I inspect?
AI response:
The query referenced a column that is not in the orders table. Check whether the intended join key is orders.customer_id. Then rerun the query and confirm the output grain and row count. Do not guess a new column name without checking the schema.That kind of answer is helpful because it points you back to the database instead of asking you to trust the model.
Set up your editor safely
Most SQL editors now have a chat panel, inline completion, or extension marketplace. Use the convenience, but set boundaries.
First, connect the assistant to schema context, not secrets. Schema context means table names, columns, types, primary keys, foreign keys, views, and metric definitions. It does not mean production passwords, API keys, private connection strings, customer rows, access tokens, or confidential exports. If the tool needs a connection, prefer a read-only role — a database identity that can inspect and query but cannot change data. That single choice turns many bad AI suggestions into harmless errors instead of writes.
Second, keep copy/paste discipline. Paste prompts from your notes into the chat. Copy AI SQL into a scratch tab, not straight into a migration, dashboard, or app repository. Format it into the house style: UPPERCASE keywords, named columns, qualified columns in multi-table queries, and stable ORDER BY when row order matters. If the draft contains SELECT *, vague aliases, unlabeled metrics, or a join you cannot explain, treat that as a review finding.
Third, ask smaller questions. "Explain this error" is safer than "fix my whole query." "Translate this SQL Server TOP query to PostgreSQL and list uncertain parts" is better than "make this portable." "Suggest names for these three CTEs" is low risk and often valuable. Naming help is underrated: a model can turn x, y, and final into paid_orders, customer_totals, and ranked_customers, making the query easier for humans to review.
Finally, keep AI out of write paths until you have guardrails. Never let a chat tool run UPDATE, DELETE, ALTER, or migration SQL against production on your behalf. You already learned the course law: rehearse, write, verify. AI does not repeal it.
This lesson gave you the safe shape: AI drafts, you read, the database proves. Next, 21.2 turns that into better prompts by showing why the schema is the prompt and why metric definitions beat repeated explanations.
Checkpoint
Answer all three to mark this lesson complete