Skip to content

Free tool · SQL

AI SQL query generator (text to SQL)

Describe what you need in plain English and paste your tables: get one SQL query and how it works, in 1 free run a day on GPT-6 Luna, no account needed. We ran every model's queries on a sample database to see whose rows were right.

1 free run a day, no account needed

GPT-6 Luna

Up to 1,500 characters. No files, tools or web search in a free run. One free run a browser, and one a network each day, shared with the free message on our home page.

Try an example:

By running it, you agree to the Terms and Privacy Policy and confirm you’re 18 or older. We keep what you send and its answer for 7 days, or in your account if you sign up.

Test runs checked .

AI SQL query generator: three examples

Three inputs and the query a free run gave each, made once on September 28, 2026 with GPT-6 Luna and shown as it came back. The example buttons in the box above show the same.

Top customers

Tables: customers(id, name, email, created_at) orders(id, customer_id, total_amount, status, created_at) Question: the 5 customers who spent the most on paid orders this year, with their total.

```sql
SELECT
  c.id,
  c.name,
  c.email,
  SUM(o.total_amount) AS total_spent
FROM customers AS c
JOIN orders AS o
  ON o.customer_id = c.id
WHERE o.status = 'paid'
  AND o.created_at >= date_trunc('year', CURRENT_DATE)
  AND o.created_at < date_trunc('year', CURRENT_DATE) + INTERVAL '1 year'
GROUP BY c.id, c.name, c.email
ORDER BY total_spent DESC, c.id
LIMIT 5;
```

This sums paid orders placed during the current calendar year for each customer.
The date range includes January 1 and excludes January 1 of next year.
Customers with no qualifying paid orders are omitted; ties are ordered by customer ID.
Users with no orders

Tables: users(id, email, signed_up_at) orders(id, user_id, placed_at) Question: users who signed up in the last 30 days and haven't placed an order yet.

```sql
SELECT u.id, u.email, u.signed_up_at
FROM users AS u
WHERE u.signed_up_at >= NOW() - INTERVAL 30 DAY
  AND u.signed_up_at <= NOW()
  AND NOT EXISTS (
    SELECT 1
    FROM orders AS o
    WHERE o.user_id = u.id
  );
```

The date range includes users who signed up from 30 days ago through now.
`NOT EXISTS` excludes anyone with an order, without duplicating users.
Monthly totals

Tables: invoices(id, client_id, amount, issued_on, paid_on) Question: for each month of 2026, the amount invoiced and how much of it has been paid.

```sql
WITH months AS (
    SELECT CAST('2026-01-01' AS date) AS month_start
    UNION ALL
    SELECT DATEADD(month, 1, month_start)
    FROM months
    WHERE month_start < CAST('2026-12-01' AS date)
)
SELECT
    m.month_start,
    COALESCE(SUM(i.amount), 0) AS amount_invoiced,
    COALESCE(SUM(CASE WHEN i.paid_on IS NOT NULL THEN i.amount ELSE 0 END), 0) AS amount_paid
FROM months AS m
LEFT JOIN invoices AS i
    ON i.issued_on >= m.month_start
   AND i.issued_on < DATEADD(month, 1, m.month_start)
GROUP BY m.month_start
ORDER BY m.month_start
OPTION (MAXRECURSION 12);
```

The query returns all 12 months, including months with no invoices.
Invoices are counted in the month they were issued; an invoice is treated as paid if `paid_on` is non-NULL.
The date range includes all issued dates in each month, regardless of time of day.

Which AI model is best at this? We tested every one

In our test runs of 5 AI SQL query generator inputs on 14 models, GLM 5.3 Flash, DeepSeek V4.1 Flash, Claude Haiku 4.5 and 7 more passed the most: 5 of 5. GPT-6 Luna, the model a free run is on, passed 3.

Some of these runs are missing or out of date (Claude Fable 5.1 has 0 of 5 runs scored), so this page stays out of search until they're all in.

Run on September 28, 2026: 5 inputs on 14 models, each with this tool's own instructions.

Each model's results on the tool's test inputs
ModelPassedHard onesMessages used on ProCost per runTime per run
GLM 5.3 FlashZ.ai5 of 52 of 21 each, of 60 a day on Pro$0.00024.3 s
DeepSeek V4.1 FlashDeepSeek5 of 52 of 21 each, of 60 a day on Pro$0.00048.6 s
Claude Haiku 4.5Anthropic5 of 52 of 21 each, of 250 a month on Pro$0.00152.5 s
DeepSeek V4 ProDeepSeek5 of 52 of 21 each, of 250 a month on Pro$0.00366.8 s
Grok 4.7xAI5 of 52 of 21 each, of 250 a month on Pro$0.007612.6 s
GPT-6 SolOpenAI5 of 52 of 21 each, of 125 a month on Pro$0.00234.0 s
Kimi K3Moonshot5 of 52 of 21 each, of 125 a month on Pro$0.00267.4 s
Gemini 3.1 Pro (preview)Google5 of 52 of 21 each, of 125 a month on Pro$0.00679.2 s
Claude Opus 5.5Anthropic5 of 52 of 21 each, of 62 a month on Pro$0.01867.1 s
GPT-6 AstraOpenAI5 of 52 of 21 each, of 31 a month on Pro$0.008713.7 s
GLM 5.3Z.ai4 of 52 of 21 each, of 250 a month on Pro$0.00111.1 s
Claude Sonnet 5Anthropic4 of 52 of 21 each, of 125 a month on Pro$0.00473.7 s
Gemini 3.8 FlashGoogle3 of 52 of 21 each, of 250 a month on Pro$0.00061.8 s
GPT-6 LunaOpenAIThe free run's model3 of 51 of 21 each, of 60 a day on Pro$0.00013.2 s
Passed: of the 5 test inputs, how many answers passed their check (an answer the provider failed to give isn't counted). Messages used: what each run counted as on Pro, and Pro's count on the model. Cost: what OpenRouter charged us per run, on average; in llmwise you pay per message, not per token. Time: from sending to the whole answer.

Side by side: a second order within 60 days

The same input on GLM 5.3 Flash and GPT-6 Luna, as each answered it, unedited.

Write one SQL query for this, in a ```sql code block, then a few lines on how it works. Use only these tables and columns. Write it for SQLite.

---
Tables (SQLite):
CREATE TABLE customers (id INTEGER PRIMARY KEY, name TEXT NOT NULL, country TEXT NOT NULL, signed_up TEXT NOT NULL);
CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT NOT NULL, category TEXT NOT NULL, price_cents INTEGER NOT NULL);
CREATE TABLE orders (id INTEGER PRIMARY KEY, customer_id INTEGER NOT NULL REFERENCES customers(id), ordered_on TEXT NOT NULL, status TEXT NOT NULL);
CREATE TABLE order_items (order_id INTEGER NOT NULL REFERENCES orders(id), product_id INTEGER NOT NULL REFERENCES products(id), quantity INTEGER NOT NULL);

Question: the customers whose second order came within 60 days of their first, ignoring cancelled orders and ordering each customer's orders by date. Return only their names, sorted by name.
GLM 5.3 Flash
```sql
SELECT c.name
FROM (
  SELECT customer_id,
         ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY ordered_on, id) AS rn
  FROM orders
  WHERE status <> 'cancelled'
) ranked
JOIN (
  SELECT customer_id,
         MIN(ordered_on) AS first_order,
         MAX(ordered_on) AS second_order
  FROM (
    SELECT customer_id, ordered_on,
           ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY ordered_on, id) AS rn
    FROM orders
    WHERE status <> 'cancelled'
  ) r
  WHERE rn <= 2
  GROUP BY customer_id
  HAVING COUNT(*) = 2
) s ON s.customer_id = ranked.customer_id
JOIN customers c ON c.id = ranked.customer_id
WHERE CAST(julianday(s.second_order) - julianday(s.first_order) AS INTEGER) <= 60
GROUP BY c.id, c.name
ORDER BY c.name;
```

- Cancels are filtered out first, and orders are numbered per customer by date (with `id` as a tie-breaker so duplicate dates get a stable order).
- The second CTE keeps only customers with at least two non-cancelled orders (`HAVING COUNT(*) = 2` after taking rows 1–2) and gets their first and second order dates.
- `julianday()` converts the date strings so the gap can be compared to 60 days; `GROUP BY c.id` prevents duplicate names if two customers share a name, and results are sorted by name.
- Note: since `signed_up`, `products` etc. aren't needed, they're untouched; adjust `<= 60` to `< 60` if "within" should be exclusive of exactly 60.
GPT-6 Luna
```sql
WITH ranked_orders AS (
  SELECT
    customer_id,
    ordered_on,
    ROW_NUMBER() OVER (
      PARTITION BY customer_id
      ORDER BY ordered_on, id
    ) AS order_rank
  FROM orders
  WHERE status <> 'cancelled'
)
SELECT c.name
FROM customers AS c
JOIN ranked_orders AS first_order
  ON first_order.customer_id = c.id
 AND first_order.order_rank = 1
JOIN ranked_orders AS second_order
  ON second_order.customer_id = c.id
 AND second_order.order_rank = 2
WHERE julianday(second_order.ordered_on) - julianday(first_order.ordered_on) <= 60
ORDER BY c.name;
```

The query ranks each customer’s non-cancelled orders by date, using order ID to break date ties.
It returns the customer’s name when the second order was no more than 60 days after the first.
Customers without two non-cancelled orders are excluded.

How the inputs are scored

  • Query result: the query runs on a small sample shop database (SQLite) and must return the same rows as our reference query.

The inputs: a filter and a sort, including customers with no orders, units sold, with ties, a second order within 60 days, and each category's share of revenue. Every model gets the tool's own instructions and up to Pro's reply limit. The method is the same as our other test runs.

How to use the AI SQL query generator

  1. Paste your tables as “table(column, column, …)” or as CREATE TABLE statements, then your question in plain English. Up to 1,500 characters.

  2. Pick your database: PostgreSQL, MySQL, SQLite or SQL Server.

  3. Press “Write the query”. Without an account you see the start (1 free run a day, no account needed).

  4. Run it on a copy or with a LIMIT first, and check a few rows by hand.

Tips for a better answer

  • Paste the real columns

    Paste the CREATE TABLE statements, or at least every column you might need. The query can only be as right as the tables it knows.

  • Say what one row means

    Say what a row of the answer is: “one row per customer”, “one row per month”. It decides the GROUP BY for you.

  • Mention the empty cases

    “Customers who never ordered”, “including months with no sales”: say whether empty cases count, or the query will quietly drop them.

  • Big schemas when signed in

    Signed in, paste a much larger schema (up to 20,000 characters) and keep refining the query in the chat.

What a good query looks like

  • The right rows, not just no error

    Run it and look at the rows, not just whether it runs. A query that joins orders to their items can count an order twice; totals that look high usually mean a join multiplied them.

  • Only your columns

    Every table and column in the query should be one you gave. An invented column (a “total” your table doesn't have) is the most common way text-to-SQL goes wrong.

  • NULLs and missing rows

    Customers with no orders, products never sold, a NULL in the middle of a sum: ask yourself whether they should be in the answer, and check the query agrees.

  • Your database's dialect

    Dates, string concatenation and “top N” differ between PostgreSQL, MySQL, SQLite and SQL Server. The query should use your database's way.

What's free, and what signing up adds

  • Without an account: 1 free run a day, on GPT-6 Luna, shared with the free message on our home page. It takes up to 1,500 characters, writes up to about 600 tokens (roughly 450 words), and shows you the start of the query.

  • Signing up is free, with an email link and no card. llmwise accounts are for people 18 and older. The query you ran comes with you as your first chat, and you get 5 free messages on almost every model (all but Claude Fable 5.1, Claude Opus 5.5, and GPT-6 Astra).

  • Signed in, paste up to 20,000 characters in a run. It runs on the model you pick, on your plan, shows the whole answer, and you can carry on in the chat with any model.

More free tools are on the tools page, and what each plan gives is on pricing.

Questions

Is the SQL query generator free?

Yes. Without an account you get 1 run a day on GPT-6 Luna, shared with the free message on our home page: you see the start of the answer, and the rest when you sign up. Signing up is free and adds 5 free messages on almost every model in llmwise (all but Claude Fable 5.1, Claude Opus 5.5, and GPT-6 Astra), with no card.

Does it connect to my database?

No. It only sees what you paste: table and column names are enough, and it never needs your data. Don't paste passwords, keys or customers' personal data.

Which SQL dialects does it support?

PostgreSQL, MySQL, SQLite and SQL Server. Pick yours: dates, limits and string functions are written the way your database expects.

Can it write UPDATE or DELETE queries?

It writes read-only SELECT queries by default. If you ask for an UPDATE or DELETE it writes one with a warning to run it inside a transaction and check the row count first.

Which AI writes the most accurate SQL?

Our test runs below ran every model's query on the same sample shop database and compared its rows with the right answer's, from a simple filter to a date gap between orders.

Which AI is best for this, in your tests?

In our test runs of 5 AI SQL query generator inputs on 14 models, GLM 5.3 Flash, DeepSeek V4.1 Flash, Claude Haiku 4.5 and 7 more passed the most: 5 of 5. GPT-6 Luna, the model a free run is on, passed 3. The table on this page has every model's result, what a run counts as on Pro, and the time it took.

Claude, GPT, Gemini, DeepSeek, Grok, Kimi, and GLM, in one chat.

See what a message costs before you send it. Free is 5 messages to try; sign in with an email link, no password or card.