All guides

Learn

Why text-to-SQL gets joins wrong on real databases, and what fixes it

Updated 20 October 2026 · Antcluster team

Text-to-SQL (also called NL2SQL or text2SQL) turns a question in plain language into a SQL query and runs it. Today's language models write valid SQL with ease. On real company databases the failures come from missing context: which join is real, which filter applies, what a code means, which of two "revenue" columns is the right one. The query runs and returns a number, and the number is wrong. Nothing in the output tells you so.

That's the problem worth solving. Syntax errors announce themselves, while a wrong join returns a tidy table.

How text-to-SQL works

Most text-to-SQL systems follow the same loop. They read the schema (table names, column names and types, sometimes a few sample rows), put it in the prompt with your question, ask the model for a query, run it, and show you the result. Better systems add retries when the SQL fails to run, and examples of good queries for similar questions.

On a tidy demo schema with columns named customer_name and order_total, that loop works well. On a 1,500-table ERP with columns named ref2 and stat_cd, the model is reading a map with the labels rubbed off.

Five ways text-to-SQL goes wrong on a real schema

1. It guesses the join

Two tables both have a product_id. The model joins them. One came from the e-commerce system and one from the warehouse system, the IDs overlap by coincidence, and the result mixes products that have nothing to do with each other.

2. It gets the grain wrong

The model sums a figure across a table that holds one row per shift when the question was per day, or joins a one-to-many relationship and counts the parent rows several times. The total comes out double, and it looks plausible.

3. It misses a business rule

Revenue should exclude test accounts and internal orders. Energy-per-unit should leave out the EV chargers on the same meter. Nobody wrote these rules into the schema, so the model can't know them.

4. It can't read the codes

A status of 9 means "cancelled by customer". In some systems one generic column holds every kind of value, and a numeric question ID decides whether the value is a meter reading or a production count. The model sees numbers and treats them as numbers.

5. It uses the wrong definition

There are often two defensible ways to compute a figure, and the business has agreed on one. In one plant, the executive dashboard showed monthly OEE (overall equipment effectiveness) at 80 to 82%. The calculation relied on a wrongly set cycle-time standard. Measured against the cycle times the plant was actually recording, OEE came out far below the dashboard figure. The SQL behind the dashboard ran perfectly every month. The full story is here.

Why not just point Claude or ChatGPT at the database?

It's a fair question, and for some databases the honest answer is: do that. If the schema is small, the names are clear and you're the one checking the output, a good model with read access will get you far.

It breaks down in a few predictable places:

  • The meaning isn't in the schema. It lives in people's heads, in old queries or in application code, and a bigger model can't read what was never written down.
  • Nothing carries over between sessions. You correct the join on Monday, and on Wednesday a colleague's session makes the same mistake.
  • The data can't go to an outside model. Regulated firms, and anyone holding client data under contract, often can't paste schemas and rows into a chat window.
  • Nobody can check the answer. A chat reply gives you a number, and a finance team needs to see the SQL and the records behind it before the number goes into a report.

In all four cases the model is good enough. What's missing is structure: a coding agent gets it from the codebase, and a text-to-SQL agent needs it supplied.

What a context-aware text-to-SQL system needs

  • Joins split into declared (in the schema) and inferred (from the data), each inferred one with its evidence and a confidence level.
  • Agreed definitions for the metrics people ask about, reused every time the question comes up.
  • The SQL your team already trusts, used as the starting point.
  • Rules a result must pass, with the option to refuse. A system that can say "I can't answer this reliably" is worth more than one that always answers.
  • The SQL and source records returned with every answer, so a person can check.

Antcluster's agent is built that way: it checks before it codes.

How Antcluster answers questions on your database

Antcluster connects read-only to your relational databases and builds the context a text-to-SQL agent is missing. Here is what that makes possible.

Ask what the business already knows

Ask in plain language and get the answer with the SQL and the records behind it. You don't hand-build a semantic layer first, and nobody writes SQL for each new question.

Turn what people know into context the agent can use

Antcluster proposes meanings for cryptic columns and codes, and finds joins nobody declared, using profiles of the data and the SQL your team already trusts. Declared foreign keys and inferred joins stay separate, and every inferred join shows its evidence. Your engineers approve or reject. When someone rejects a join, it stays rejected.

Ask the questions nobody thought to ask

With the meanings connected, people can follow questions that cross tables and teams, and Antcluster returns what it finds as candidates with evidence. Someone who knows the business decides which ones hold.

Why this is possible now

Coding agents such as Claude Code changed what small software teams attempt. A few engineers can now try work that used to need many more, like porting a whole console game to PC or writing GPU shaders in a short window. They can, partly, because a coding agent works inside a harness: an environment with the tools and context it needs, where the tests and the build tell it immediately when it's wrong.

Text-to-SQL on its own has no harness. The agent writes a query and the database runs it, and nothing objects to a wrong join. Give the agent a structure of agreed meanings and rules to check against, and it can do for data what coding agents now do for software. The result is that people stop spending each investigation reconstructing what the data means, and spend it on the question. Data teams get room to build the use cases they'd shelved. Business teams in finance or operations, at a small firm or a large enterprise, get to investigate risks and problems directly, including ones nobody had thought to ask about.

Each answer makes the next one better

The database, the agent and its context move together. An investigation can leave behind an approved definition or a corrected join, and later questions start from there. The ontology underneath is written in OWL 2 and expands itself as approved findings and new tables arrive, with an engineer reviewing changes. Questions your team has settled get the same logic each time, and new questions come back with the assumptions behind them listed.

Scored on your own questions

We don't quote public leaderboard scores, because a score on someone else's database says little about yours. Before a pilot, we agree a set of your own questions with known answers, and a pass mark, and score Antcluster against them.

Try it on questions you already know the answers to

Connect one database read-only, inside your network if you prefer, and bring questions your team has already answered. We'll show you Antcluster's answers next to yours, with the SQL behind each one.

Questions about text-to-SQL

What is the difference between text-to-SQL, NL2SQL and text2SQL? None in practice. They're three names for turning a natural-language question into a SQL query.

How accurate is text-to-SQL? On a company's own database, accuracy depends mostly on context: whether the system knows the real joins, the agreed definitions and the business rules. Measure it on your own questions.

Can ChatGPT or Claude write SQL for my database? Yes, and on a small, well-named schema they'll often get it right. On a large or legacy database, they'll write valid SQL that can still be wrong, because the meaning of the data isn't in the schema.

Is my data sent to the language model? With Antcluster, the database connection is read-only, and the only outside component is the language model, which you choose from the ones we support. On-premises setups keep model traffic inside your network.

Does text-to-SQL replace analysts? It changes their job. Analysts and domain experts review what the agent produces and approve the meanings, much as engineers review a coding agent's work.