How to Use AI to Write SQL Queries from Plain English (2026 Guide)
Turn plain-English questions into correct SQL with ChatGPT, Claude or Gemini: share your schema, name your dialect, then test, check and optimize the query.

Table of contents
Difficulty
Beginner
Time required
30 minutes
Tools needed
- ChatGPT
- Claude or Gemini (free tier is fine)
- Your database schema
- A SQL client with read-only access
You have a question like "which product categories made the most money last month?" and a database that holds the answer. You just don't write SQL every day, or you do and you're tired of typing the same joins. An AI chatbot can turn that sentence into a working query in seconds.
Here's the short version of how to do it well: give the AI your table definitions (never real customer rows), tell it which SQL dialect you use, describe the question with exact definitions, then test the result on a small sample with a read-only account before you trust it. That last part is where most people cut corners, and it's where most wrong answers slip through.
Why so cautious? Because AI-written SQL fails quietly. A broken query throws an error, which is fine. A query that runs and returns a plausible but wrong number is the real danger, and research benchmarks show that still happens a lot. This guide walks through eight steps, with a sample online store schema and four worked questions that get progressively harder.
Why you can't skip checking the SQL
Text-to-SQL is one of the most heavily benchmarked AI tasks, and the numbers are humbling. On the BIRD benchmark, which uses real-world-style databases with messy values, the top system on the leaderboard scored 82.39% execution accuracy on the test set as of September 2026 (Huawei's DataGallery-Text2SQL, submitted August 2026). Human data engineers and database students scored 92.96%. So even the best specialized systems get roughly one in six questions wrong.
Harder, enterprise-style tasks are worse. The Spider 2.0 paper, an ICLR 2025 oral presentation, reported that an agent built on OpenAI's o1-preview solved only 21.3% of its tasks, compared with 91.2% on the older Spider 1.0 and 73.0% on BIRD. The Spider 2.0 leaderboard has climbed since then (the top Spider 2.0-Lite entry was at 76.23% in September 2026), but those are purpose-built agent systems, not a chatbot you pasted a question into.
Your everyday questions are usually simpler than benchmark tasks, and your schema is probably smaller. Still, the lesson holds: treat AI-generated SQL like code from a smart new hire. Usually good, occasionally confidently wrong.
The example schema we'll use
Every example below uses this small online store in PostgreSQL. Copy the pattern for your own tables.
CREATE TABLE customers (
customer_id BIGINT PRIMARY KEY,
email TEXT NOT NULL UNIQUE,
full_name TEXT,
country TEXT, -- ISO code, can be NULL
created_at TIMESTAMPTZ NOT NULL
);
CREATE TABLE products (
product_id BIGINT PRIMARY KEY,
name TEXT NOT NULL,
category TEXT NOT NULL,
price NUMERIC(10,2) NOT NULL
);
CREATE TABLE orders (
order_id BIGINT PRIMARY KEY,
customer_id BIGINT NOT NULL REFERENCES customers(customer_id),
status TEXT NOT NULL, -- 'pending','paid','shipped','cancelled','refunded'
ordered_at TIMESTAMPTZ NOT NULL
);
CREATE TABLE order_items (
order_item_id BIGINT PRIMARY KEY,
order_id BIGINT NOT NULL REFERENCES orders(order_id),
product_id BIGINT NOT NULL REFERENCES products(product_id),
quantity INT NOT NULL,
unit_price NUMERIC(10,2) NOT NULL -- price at time of sale
);Notice the comments. Telling the AI that status has five specific values and that unit_price is the price at the time of sale prevents two of the most common mistakes: guessing status names and calculating revenue from today's product price.
Step 1: Give the AI your schema, not your data
The AI needs to know your table names, column names, data types and how tables connect. It does not need a single real customer record.
The easiest way to get your schema in PostgreSQL is
pg_dump --schema-only, or in most SQL clients you can right-click a table and copy its CREATE statement. A plain list of tables and columns works too, but CREATE TABLE statements are better because they include types, keys and constraints.Add short notes about anything a stranger wouldn't guess: what each status value means, which timestamp is in which time zone, whether amounts are in cents or dollars, and which columns can be NULL.
Step 2: Name your SQL dialect and version
SQL isn't one language. Date functions, string handling,
LIMITversusTOP, and even quoting rules differ between PostgreSQL, MySQL, SQLite, BigQuery (GoogleSQL) and SQL Server (T-SQL). If you don't say which one you use, the AI will guess, and it often guesses PostgreSQL or MySQL.A few examples of how the same idea changes:
Task PostgreSQL MySQL SQL Server BigQuery First 10 rows LIMIT 10LIMIT 10TOP 10LIMIT 10Start of month date_trunc('month', ts)DATE_FORMAT(ts, '%Y-%m-01')DATETRUNC(month, ts)(2022+)TIMESTAMP_TRUNC(ts, MONTH)30 days ago now() - interval '30 days'NOW() - INTERVAL 30 DAYDATEADD(day, -30, GETDATE())TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)Include the version if you know it. Newer versions add functions that older ones lack, and the AI can't tell which you have.
Step 3: Describe the question precisely
"Show me top customers" is ambiguous. Top by what? Over what period? Do refunds count? The AI will quietly pick answers to all of those questions, and you won't know which ones it picked.
Spell out the definitions a colleague would ask about. Here's a reusable prompt that bundles Steps 1 to 3:
Prompt: generate a SQL query You are a careful SQL analyst. Write a query for PostgreSQL 16. Schema: [paste CREATE TABLE statements with comments] Question: Revenue by product category for last calendar month. Definitions: - Revenue = quantity * unit_price from order_items - Only count orders with status 'paid' or 'shipped' - "Last month" means the previous calendar month in America/New_York time - Timestamps are stored as TIMESTAMPTZ Rules: - Use only tables and columns in the schema. If something is missing, ask me instead of guessing. - List any assumptions you made. - Read-only: SELECT statements only.The "list any assumptions" line is the most useful sentence in that prompt. It turns hidden guesses into a checklist you can review. For more ways to tighten prompts, see our guide to writing better prompts.
Step 4: Generate the query and start simple
Paste the prompt into ChatGPT, Claude or Gemini. Any of the major chatbots handles everyday SQL well; our Claude vs ChatGPT for coding comparison covers the differences if you're choosing one.
Here are four questions against the store schema, from easy to tricky, with correct PostgreSQL answers. Use them as a reference for what good output looks like.
Question 1 (easy): "How many new customers signed up in the last 30 days, by country?"
SELECT COALESCE(country, 'Unknown') AS country, COUNT(*) AS new_customers FROM customers WHERE created_at >= now() - interval '30 days' GROUP BY COALESCE(country, 'Unknown') ORDER BY new_customers DESC;The
COALESCEmatters: without it, customers with no country show up as a blank row that's easy to overlook.Question 2 (medium): "Revenue by product category last calendar month, in New York time."
WITH bounds AS ( SELECT (date_trunc('month', now() AT TIME ZONE 'America/New_York') - interval '1 month') AT TIME ZONE 'America/New_York' AS start_ts, date_trunc('month', now() AT TIME ZONE 'America/New_York') AT TIME ZONE 'America/New_York' AS end_ts ) SELECT p.category, SUM(oi.quantity * oi.unit_price) AS revenue FROM orders o JOIN order_items oi ON oi.order_id = o.order_id JOIN products p ON p.product_id = oi.product_id CROSS JOIN bounds b WHERE o.status IN ('paid', 'shipped') AND o.ordered_at >= b.start_ts AND o.ordered_at < b.end_ts GROUP BY p.category ORDER BY revenue DESC;The double
AT TIME ZONEconverts "now" to New York local time, finds midnight on the first of the month there, then converts that back to an absolute timestamp. Filtering with "on or after the start, strictly before the end" avoids missing orders placed at 11:59:59 p.m. on the last day.Question 3 (harder): "Which customers ordered in 2025 but haven't ordered at all in 2026?"
SELECT c.customer_id, c.email FROM customers c WHERE EXISTS ( SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id AND o.status <> 'cancelled' AND o.ordered_at >= TIMESTAMPTZ '2025-01-01 00:00 America/New_York' AND o.ordered_at < TIMESTAMPTZ '2026-01-01 00:00 America/New_York' ) AND NOT EXISTS ( SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id AND o.status <> 'cancelled' AND o.ordered_at >= TIMESTAMPTZ '2026-01-01 00:00 America/New_York' );NOT EXISTSis the safe way to say "has no matching rows." AI tools sometimes writeNOT IN (SELECT customer_id ...)instead, which returns nothing at all if the subquery contains a single NULL.Question 4 (advanced): "Monthly revenue with the percentage change from the previous month."
WITH monthly AS ( SELECT date_trunc('month', o.ordered_at AT TIME ZONE 'America/New_York') AS month, SUM(oi.quantity * oi.unit_price) AS revenue FROM orders o JOIN order_items oi ON oi.order_id = o.order_id WHERE o.status IN ('paid', 'shipped') GROUP BY 1 ) SELECT month, revenue, LAG(revenue) OVER (ORDER BY month) AS prev_revenue, ROUND( 100.0 * (revenue - LAG(revenue) OVER (ORDER BY month)) / NULLIF(LAG(revenue) OVER (ORDER BY month), 0), 1 ) AS pct_change FROM monthly ORDER BY month;LAGpulls the previous row's value, andNULLIFprevents a divide-by-zero error. One catch: a month with no sales simply doesn't appear, so "previous month" could actually be two months back. If that's possible in your data, ask the AI to fill gaps withgenerate_series.Step 5: Ask the AI to explain the query line by line
Before running anything, ask for an explanation. It's the fastest way to catch a mismatch between what you meant and what the AI built.
Prompt: explain and self-check Explain this query line by line in plain English. Then tell me: 1. Which rows are included and excluded, and why 2. Anything that could double-count (joins, one-to-many relationships) 3. How NULLs are handled in each filter and aggregate 4. Which time zone each date comparison usesIf the explanation says something you didn't intend ("includes refunded orders"), fix the prompt, not just the query. That way the next query starts from the right definitions.
Step 6: Test on a small sample with read-only access
Never run AI-generated SQL for the first time against production with an account that can change data. Two habits cover most of the risk.
Use read-only credentials. In PostgreSQL, a database admin can create a role that can only read:
CREATE ROLE analyst_ro LOGIN PASSWORD 'change-me'; GRANT CONNECT ON DATABASE shop TO analyst_ro; GRANT USAGE ON SCHEMA public TO analyst_ro; GRANT SELECT ON ALL TABLES IN SCHEMA public TO analyst_ro;Even if the AI slips in an UPDATE or DELETE, that account can't run it. Querying a replica or a staging copy is even safer.
Start small. Add
LIMIT 20to row-level queries, or narrow the date range to one day, and eyeball the output. Then sanity-check totals against something you already know, such as the revenue figure in your payments dashboard or the order count in your store admin. If the AI's number is 3x higher than your dashboard, something is double-counting.Step 7: Check the classic edge cases
Most wrong-but-plausible queries fail in one of three places.
NULLs.
WHERE country <> 'US'silently drops customers whose country is NULL, because comparisons with NULL are never true.AVGandCOUNT(column)ignore NULLs, whileCOUNT(*)doesn't.Duplicates from joins. Joining orders to order_items produces one row per item, not per order. Ask for "number of orders per customer" and a careless query counts items instead. The fix is
COUNT(DISTINCT o.order_id):SELECT c.customer_id, c.email, COUNT(DISTINCT o.order_id) AS orders, SUM(oi.quantity * oi.unit_price) AS lifetime_revenue FROM customers c JOIN orders o ON o.customer_id = c.customer_id JOIN order_items oi ON oi.order_id = o.order_id WHERE o.status IN ('paid', 'shipped') GROUP BY c.customer_id, c.email ORDER BY lifetime_revenue DESC LIMIT 10;The same trap applies if you join two one-to-many tables at once (say, order items and payments): sums get multiplied. Aggregate each table in its own CTE first, then join.
Time zones. "Yesterday" in UTC isn't yesterday in Los Angeles. If your timestamps are stored in UTC and your business reports in local time, say so explicitly, as in Question 2.
Step 8: Optimize, then save it as a reusable query
Once the numbers are right, check the speed. Run
EXPLAINin front of the query to see the plan without executing it, and paste the plan into the chat:Prompt: optimize a slow query Here is my PostgreSQL query and its EXPLAIN output. The orders table has about 5 million rows. Suggest indexes or rewrites that would make it faster, and explain the trade-offs. Don't change the results. [paste query] [paste EXPLAIN output]Be careful with
EXPLAIN ANALYZE: it actually runs the query, so it can be slow on big tables and will execute any data changes. Typical suggestions, like an index onorders (ordered_at)ororders (customer_id), need a quick review from whoever owns the database.Finally, save the query somewhere you'll find it again: a saved query in your SQL client, a view, or a file in your team's repo. Add a comment at the top with the plain-English question, the definitions you used and the date you checked it. Future you will thank present you.
Built-in AI in database tools
If your data lives in a cloud warehouse, you may not need a separate chatbot. These built-in assistants already see your schema, which removes Step 1, though you still need Steps 5 to 7.
- BigQuery: Gemini in BigQuery can generate SQL from a natural-language comment in the query editor, explain queries and suggest fixes.
- Databricks: Genie Code, which replaced Databricks Assistant in 2026, generates and explains SQL in the SQL editor and notebooks, and has an
/optimizecommand for query performance. - Snowflake: CoCo (formerly Cortex Code) writes and edits SQL inside Snowsight workspaces, while Cortex Analyst is aimed at business users asking questions in plain English.
- Supabase: the Supabase AI Assistant in the dashboard's SQL editor turns prompts into Postgres queries and shows a diff you accept or reject.
Pricing and availability vary by plan and region, so check your account before counting on any of these. Code editors like Cursor and GitHub Copilot can also write SQL inside your project files; our roundup of the best AI coding assistants for developers compares them, and if you're just starting out, see the best free AI coding assistants for beginners.
Where to go next
If a query errors out and you can't see why, our guide to debugging code faster with AI applies to SQL errors too. And if your data actually lives in a spreadsheet rather than a database, AI for Excel and Google Sheets formulas is the better starting point.
Frequently asked questions
Can ChatGPT write SQL queries?
Yes. ChatGPT, Claude and Gemini all write solid SQL for common questions, especially when you give them your schema and dialect. They're less reliable on complex, multi-step questions and on databases with unclear column names, so always review, test on a sample and compare totals against a number you trust.
Is it safe to give my database schema to an AI?
Table and column names are usually low risk, but they can reveal business details, so check your company's policy first. Never paste real customer data, passwords or connection strings. Many companies prefer the built-in assistants in their warehouse, which keep everything inside an account they already control.
How accurate is AI at writing SQL?
It depends heavily on the task. On the BIRD benchmark, the best system scored 82.39% as of September 2026, against 92.96% for humans. On the tougher Spider 2.0 tasks, the original paper's o1-preview agent solved only 21.3%. For simple questions on a small, well-documented schema, results are much better, but you still need to check.
Do I still need to learn SQL if AI can write it?
You need enough SQL to read a query and spot problems: SELECT, WHERE, JOIN, GROUP BY and how NULLs behave. AI makes writing faster, but you're still responsible for whether the answer is right. Asking the AI to explain every query it writes is a good way to learn as you go.
Which AI is best for writing SQL?
For one-off questions, any major chatbot works well. If your data is in BigQuery, Databricks, Snowflake or Supabase, the built-in assistant is often the better choice because it already knows your schema. Inside a codebase, an AI coding assistant is the most convenient.

Written by
Panoptix Editorial Team
Our editors test AI tools hands-on for weeks before we publish a word. We pay for our own subscriptions and never accept payment for rankings.
How we test AI tools →

