---
title: "Trace an AI answer to its SQL: from number to source table"
canonical: "https://www.owox.com/blog/articles/ai-analytics-hallucinations-sql-traceability"
updated: "2026-10-15"
---

# Trace an AI answer to its SQL: from number to source table

When someone brings you an AI answer and asks if it can be used, you can follow it back through six links: the sentence, the Data Mart it names, the written definition, the SQL that ran, the source table and the rows. We traced 15 answers this way on our demo project. Thirteen reached the end of the trail, eleven matched to the cent, and one broke at link 4, where the connector did not expose the source table of a Data Mart on a different warehouse, and that Data Mart also had no written description. This guide gives the trace card, the checklist, the rule for when the trail breaks and the record to send back.

[AI in Analytics](/blog/topics/ai) · Updated October 14, 2026 · [Ievgen Krasovytskyi](/team/ievgen-krasovytskyi) · 14 min read

![Trace an AI answer to its SQL: from number to source table](https://cdn.owox.ai/www/content-marketing-article/ai-analytics-hallucinations-sql-traceability/thumbnail/2.png/public)

A message arrives: “The AI says net revenue for the week was $64,717.20. Can we put it in the update?” You did not run the query, and you are the one who will be asked where the number came from. (The figures on this page come from our demo project, not from your company.)

This page is the procedure for that moment. It follows one AI answer back through six links, from the sentence to the Data Mart, the SQL that ran, the source table and the rows, and it ends with a record you can send back to the person who asked. **A trace does not make an answer right. It makes a wrong one findable.** It starts after the answer exists and does not explain [how a model invents SQL](/blog/articles/ai-analytics-hallucination-deterministic-sql) or [how to connect one](/blog/articles/bigquery-mcp-claude).

**_Note:_** _Originally published in July 2026. Fully updated in October 2026._

## The six links between an AI sentence and your data

An answer from an [AI assistant](/product/ai-assistants) that reads a governed Data Mart leaves a chain behind it. Each link has one question and one place to look. In OWOX Data Marts, the connection between the assistant and your Data Marts is the MCP server.

| What you are checking | The link, in product words |
| --- | --- |
| 1\. Where did the answer say it came from? | Sentence to Data Mart. The answer should name it |
| 2\. What does that source say the figure means? | Data Mart to definition: its description and fields |
| 3\. What exact calculation ran? | Definition to SQL: Run History, the executed SQL |
| 4\. Which raw table did the calculation read? | SQL to source table: the configuration of the Run History entry |
| 5\. Can I get the same figure myself from that table? | Source table to rows: plain read-only SQL |
| 6\. Do the two numbers agree? | Rows to the answer: to the cent, or at the answer’s own rounding |

Run History is the record of each query an assistant ran against a Data Mart. An entry shows the SQL that was executed, the source table, the row count, a flag that says whether the result was cut off at the row limit, and when the source tables were last updated. [It keeps the request and the SQL, never the rows](/blog/articles/can-you-trust-ai-business-numbers), so you reproduce the figure rather than read it back.

**If your assistant has no record like Run History**, ask it for three things: the SQL it ran, the tables it read, and when they were last updated. If it cannot produce all three, treat the number as a draft. BigQuery’s job history is one such record. In our tests it labelled jobs started through Google’s MCP server with `goog-mcp-server=true` and kept the query text. On four questions answered on raw BigQuery views, what was missing was a written definition: the assistant had only column names. In a separate test the same day, a refused call left no job at all, so a missing job can mean the call never ran. [The job-history route is described here](/blog/articles/ai-analytics-on-bigquery).

## One answer traced, link by link

The question was “What was our net revenue for 21-27 September 2026?” The answer said $64,717.20 (USD), net of Cancelled and Returned orders, filtered by order date, from the Purchases Data Mart joined to Orders. The auditors were separate AI sessions, each given only the answer text and the Run History record, never the conversation; for a number going to a board, a person should still re-run the query. This is one auditor’s trace, shortened from its own notes.

| Link | What the auditor found |
| --- | --- |
| 1 | The answer names Purchases. One Purchases Data Mart exists, published. |
| 2 | The description says one row per order line, revenue recognised only for completed orders. The field `line_net_revenue` is “Item Net Revenue”, Completed only, Cancelled and Returned count as 0. It matches the answer’s wording. |
| 3 | Run History: `SELECT SUM(main.line_net_revenue), main.currency FROM main LEFT JOIN orders_e_commerce ON main.order_id = orders_e_commerce.order_id WHERE orders_e_commerce.orders_e_commerce__order_date BETWEEN '2026-09-21' AND '2026-09-27' GROUP BY main.currency`. One row, not truncated. |
| 4 | `owox-demo.ecommerce.purchases`, joined to the orders table for the order date. |
| 5 | The auditor’s own query on both tables, with the same date filter, grouped by currency. Result: USD 64,717.20 over 275 order lines. |
| 6 | Exact. 64,717.20 against 64,717.20, one currency. |

The real Run History entry shows the full executed SQL, and the app keeps it per Data Mart; our auditors worked from a shorter copy, so a real trace is easier than ours. The audit took five tool calls, one of them a failed lookup in the wrong project. The date filter shows why link 3 matters: the Purchases table has no order date, and the SQL in Run History is where the join to Orders is visible. A query on Purchases alone has no order date to filter on; only the join to Orders makes the date filter possible.

## The Turning Point

OWOX Data Marts

See your first report built in real time. _15 minutes._

1.  Connect your data warehouse
2.  Pick your metrics
3.  Get a live Google Sheets report

In the time it takes to write a ticket. Then imagine never writing that ticket again.

[Book a Demo](/book-a-call)

We'll use your actual use case

## The trace card to keep behind any number

Keep seven things for every AI number you sign, and what each one catches.

| Field | What goes in it | What it catches |
| --- | --- | --- |
| Question as asked | The exact wording | “Revenue”, “earn” and “top line” are three requests |
| Answer as given | The figure plus its stated scope: gross or net, date basis, currency | A silent change of basis |
| Data Mart and owner | Name, and who maintains it | Nobody to ask |
| Written definition | The description and field text, quoted | A Data Mart with no definition |
| Executed SQL | From Run History, with row count and the truncated flag | A result cut at the row limit |
| Source table | The full table name and when it was last updated | Stale or unreachable data |
| Reproduced figure | Your SQL and the result: exact, rounded or different | Everything else |

To reproduce a figure, write the plainest query that matches the executed SQL and run it read-only on the source table:

```
SELECT SUM(<field>)
FROM `<project.dataset.table>`
WHERE <date field> BETWEEN '<from>' AND '<to>'
```

Copy the joins from the executed SQL, because the filter column may live in a joined table, as it did above. Compare to the cent, or at the answer’s own rounding.

**Reproducing the executed SQL proves consistency, not correctness**: it shows the answer is what that SQL returns. The independent check is to compare against the warehouse view or a figure someone already trusts.

**If your tool is ChatGPT and a CSV**, the same three requests read: which file and columns it used, the calculation it ran or the lines it added up (ask it to show the sum), and the date the file was exported. If it cannot say, the number is a draft. [Our exported-file test](/blog/articles/can-you-trust-ai-business-numbers) found a chat that added 275 lines without running code.

## Five places the trail bent without breaking

Most of what we found was not a break, and the card caught each case because it asks for the scope as well as the figure.

*   **The figure counted by a different date.** Asked for the “top line”, the assistant used the Growth Data Mart and filtered by session date, not order date. It said so, gave gross and net with both labelled, and the figure matched at the rounding it printed.
*   **The question meant something narrower.** Asked for “return on ad spend”, the assistant gave each platform’s own claimed return, said it was not the store’s recorded revenue, and left TikTok and X blank because they report no conversion value. Every figure reproduced exactly.
*   **The result was cut short.** One query for customers with more than one order hit the row limit, and Run History flagged it as truncated. The assistant split the question in two halves, and the sum of the halves, 1,576, reproduced exactly in a single query.
*   **A total with no record.** In an answer on orders by category, the total of 625 orders has no Run History entry of its own. It reproduced exactly.
*   **A number reused from memory.** In a follow-up, the assistant ran a new query for August and reused September’s 13,612.33 from its earlier answer. The auditor could verify the August side only.

The last two are one rule: **a figure with no Run History entry of its own cannot be shown to come from your data**, even when it happens to be right.

## When the trail breaks

One answer in 15 could not be taken to the source table. The question was “What was our revenue last week?” and the answer was 147,465 (our demo project’s figure, used as the example), with no currency and no gross or net label, from a Data Mart named “e-Commerce Growth Demo”. The auditor’s trace:

| Link | What the auditor found |
| --- | --- |
| 1 | Through. The answer names the Data Mart, which exists and is published. |
| 2 | Through, but the definition is empty. The description is blank, and nothing says whether revenue is gross or net or in which currency. |
| 3 | Through. Run History shows the SQL, in a different dialect from BigQuery, with 7 rows and the freshness marked unavailable. |
| 4 | Broke. The SQL reads a view in the Data Mart’s own warehouse. No source table or view definition was available to the auditor. |
| 5–6 | Not reached. A best-effort rebuild on the demo views gave 60,937.79 net and 70,912.27 gross, which is not a reproduction and does not match. |

When the same question went to the raw views, the answer was 60,937.79 net and 70,912.27 gross from 131 completed orders (155 orders for the gross figure), with the definitions and the SQL printed, and a re-run gave the same figures. The two answers come from different Data Marts, and nothing under the first one could be seen, so this is not one right answer and one wrong one. One more detail is visible without any tool: the seven daily figures printed in the 147,465 answer (18,600 + 28,975 + 19,035 + 17,485 + 16,485 + 23,155 + 16,290) add up to 140,025, not 147,465.

**The fix sits in the Data Mart, not in the assistant.** Write the description, the currency and whether revenue is gross or net, and make sure the person who maintains the Data Mart can say which table it reads. When link 2 is blank, nobody can say what the figure counts. [The third condition for trusting an AI answer](/blog/articles/can-you-trust-ai-business-numbers) is a record you can open, and this is what it looks like when part of the record is missing.

The rule we suggest: **a number is trusted when you can reach its source table and reproduce it. Otherwise it is a draft.** Where the trail stops decides what to do next. In our run we saw rows 2 to 5 of the table below; rows 1 and 6 did not occur, so those two actions are our suggestion, not something we tested.

| Where the trail stops | What to do |
| --- | --- |
| 1\. The answer names no source | Ask the assistant which Data Mart or table it used. No answer means a draft |
| 2\. Nobody wrote down what the figure means | Ask the owner to write it before the number is used again |
| 3\. The query left no record | Ask the assistant to run it again so a query leaves an entry |
| 4\. You cannot see which raw table was read | Ask the Data Mart’s owner for the table, and ask for it to be recorded |
| 5\. You cannot get the same figure | Send it back as unverified, with what you tried |
| 6\. Your figure differs | Send both figures and both definitions. Do not pick one |

## A checklist for any AI number

We did not time the traces. For an auditor holding the Run History entry, a trace took 1 to 6 tool calls. The order we would follow:

1.  Copy the answer and the question as asked.
2.  Note what it says about scope: gross or net, date basis, currency, and which Data Mart.
3.  Open that Data Mart and read its description and the fields used. Quote them.
4.  Open Run History and find the entry for that query. If there is none, stop and mark the figure a draft.
5.  Read the executed SQL, the row count and the truncated flag, and note when the source tables were last updated.
6.  Write the source table into the card.
7.  Run your own read-only query on that table, with the joins from the executed SQL.
8.  Compare to the cent, or at the answer’s own rounding, and write down “exact”, “rounded” or “different”.

## What a trace does not fix

OWOX’s aim is zero hallucinations. In the governed path the assistant does not write SQL: it sends a structured request, a Data Mart with fields, aggregations and filters, and OWOX builds the SQL from the Data Mart and the joins your analyst defined in your [data model](/product/data-modeling). The assistant can still choose the wrong field or filter, and that is what the trace checks. That lowers the risk. It is not a 100% guarantee, which is why the trail is there to be checked. [Why an accuracy score such as 90% says little about one answer](/blog/articles/text-to-sql-accuracy-benchmarks-production) is covered elsewhere.

Four things stay outside a trace:

*   **An ambiguous question.** A trace shows what was answered, not what was meant.
*   **Stale data.** Run History shows when sources were last updated; deciding whether that is recent enough is yours.
*   **A gap in the written definition.** In one of our own guides, [a trace of a Reddit spend figure](/blog/articles/marketing-analytics-data-model) located a Data Mart whose SQL divided by 100,000 where the warehouse view divided by 1,000,000, so the figure was ten times too high. The trace pointed at the place; comparing against the warehouse view is what showed the gap.
*   **The wider picture.** A trace follows one number. [Data lineage](/glossary/data-lineage) maps how all of them are built. [This guide](/blog/articles/governed-mcp-analytics) shows Run History in a governed setup, and [this one](/blog/articles/auditable-analytics-reporting-finance-governance) covers the evidence file behind each number.

## What to send back to the person who asked

Send the card, in your words, with three lines on top. Something like:

*   **What I checked:** the answer was taken from the Purchases Data Mart, read from Run History, and reproduced on the source table.
*   **What matched:** net revenue for 21-27 September, $64,717.20 in USD, exact to the cent. The date basis is order date, net means Completed orders only.
*   **What I could not check:** when the data was last refreshed, beyond the timestamp Run History shows.

If the trail broke, say where, and whether the figure was not reproduced or reproduced and different. “This is a draft until the owner writes the definition” is a complete answer, and better than a number nobody can defend.

## How we tested this

We asked 12 questions on our demo e-commerce project through the OWOX Data Marts connector, each to a fresh Claude session with no memory, plus three follow-ups in the same sessions. Each answer went to a separate AI auditor session, given only the answer and the Run History entry, which had to walk the six links and reproduce the figure in read-only BigQuery SQL. Counts, as they came out:

| Result | Answers |
| --- | --- |
| All six links, exact to the cent, reproduced from a source table | 8 |
| All six links, exact to the cent, reproduced from a SQL-defined view (the ad-spend Data Mart) | 3 |
| Reproduced at the answer’s own rounding, with links 3 and 4 only partly confirmed (no SQL text or source table shown, source inferred) | 1 |
| August figure exact on the view, September input carried from an earlier answer with no entry | 1 |
| Stopped at link 4 | 1 |
| A refusal with no figure (headcount), correctly declined | 1 |

So 13 of 15 reached the end of the trail, meaning the figure was reproduced from the table or view it came from, and 11 matched exactly. Four ad-spend answers read a view, not a source table: three in the second row above and the August figure in the fourth. The two that did not were the headcount question, a refusal with no figure to trace, and the last-week answer, whose source table the connector does not expose.

**Limits.** This is demo data, one model, and 15 answers, run in sub-agent sessions, not in a chat app. We read Run History in the app ourselves and gave the auditors an abridged transcription (the outer SELECT, the filters, the row count and the truncated flag), not the full SQL. The raw-views arm, four questions, was not audited separately: we re-ran one and it matched. The record we gave the auditors carried the last-updated line for one entry only, so the freshness statements in the answers were not checked, and two auditors (last quarter and the peak-day follow-up) worked from an entry with no join shown. We did not record wall-clock time, so we do not say how many minutes a trace takes.

## Your New Normal

Turn your data into decisions.

Governed data marts give you the clean foundation ML needs to actually work.

*   No AI hallucinations
*   Analyst-governed definitions
*   Every number traces to SQL

[Get started free](https://www.owox.com/app-signup)

## FAQ

## Frequently Asked Questions

Where can I see the SQL behind an AI answer?

In OWOX Data Marts, open Run History: each query an assistant ran against a Data Mart is recorded there with the executed SQL, the source table, the row count, a flag that says whether the result was cut off at the row limit, and when the source tables were last updated. If your assistant reads raw tables in Google BigQuery, the job history keeps the query text; in our tests it labelled jobs started through Google's MCP server with \`goog-mcp-server=true\`. If your tool can show neither, ask it for the SQL, the tables it read and when they were last updated. If it cannot give all three, treat the number as a draft.

What goes on a trace card?

Seven things: the question as asked, the answer as given with its stated scope (gross or net, date basis, currency), the Data Mart and its owner, the written definition quoted from the description and fields, the executed SQL from Run History with the row count and the truncated flag, the source table and when it was last updated, and your own reproduced figure marked exact, rounded or different. Each field catches a specific failure, such as a silent change of date basis or a Data Mart with no definition.

Can an answer from chat memory be traced?

Not to your data. If an assistant reuses a figure from its own earlier answer, that figure has no Run History entry of its own. In our test, a follow-up ran a new query for August and carried September's 13,612.33 over from the earlier answer, so the auditor could verify the August side only. The rule is that a figure with no Run History entry of its own cannot be shown to come from your data, even when it happens to be right. Ask the assistant to run the query again so it leaves an entry.

Does tracing make an AI answer 100% right?

No. A trace makes a wrong answer findable, it does not make an answer right. In the governed path the assistant does not write SQL: it sends a structured request and OWOX builds the SQL from the Data Mart, which lowers the risk of hallucination, but the assistant can still choose the wrong field or filter. Reproducing the executed SQL also proves consistency, not correctness: it shows the answer is what that SQL returns. The independent check is to compare against a warehouse view or a figure someone already trusts. An ambiguous question, stale data and a wrongly written definition stay outside a trace.

How is tracing different from data lineage?

A trace follows one number, from the AI's sentence to the Data Mart, the SQL that ran, the source table and the rows, and ends with a record you can hand back. Data lineage maps how all of your numbers are built. Use lineage to understand the pipeline, and a trace to prove or disprove the one figure someone is about to act on.

What does Run History keep, and what does it not?

It keeps the request and the executed SQL for each query an assistant ran against a Data Mart, with the source table, the row count, the truncated flag and when the source tables were last updated. It never keeps the rows, so you reproduce the figure with your own read-only query on the source table rather than read it back. It also has no entry for a figure the assistant reused from chat memory, and in one of our runs the freshness line was marked unavailable.

How long does a trace take?

We did not record wall-clock time, so we do not give a number of minutes. For an auditor holding the Run History entry, a trace took between 1 and 6 tool calls in our run of 15 answers on a demo project. Thirteen reached the end of the trail and eleven matched to the cent. The one that broke stopped at link 4 because the source table of that Data Mart was not available, and the Data Mart had no written description.

## Who wrote this

![Ievgen Krasovytskyi](https://cdn.owox.ai/www/webflow/68404586b341508a789a4aa5_.png/public)

[Ievgen Krasovytskyi](/team/ievgen-krasovytskyi) · Head of Marketing

Ievgen Krasovytskyi is the Head of Marketing at OWOX, leading strategy across content, SEO, product marketing, and AI-powered automation. With deep expertise in analytics infrastructure, data warehouses, and marketing technology, he builds systems that connect marketing performance to business outcomes. Ievgen writes about SaaS growth, analytics workflows, and the future of AI in marketing operations.

[LinkedIn](https://www.linkedin.com/in/ievgen-krasovytskyi-a38a1253/) · [All articles](/team/ievgen-krasovytskyi)

[AI in Analytics](/blog/topics/ai)

## Related articles

[AI in Analytics · AI analytics agents replace your backlog, not your analyst · July 2, 2026](/blog/articles/ai-analytics-agent-replace-backlog)

[AI in Analytics · AI hallucinating SQL: what it looks like and how to catch it · October 14, 2026](/blog/articles/ai-analytics-hallucination-deterministic-sql)

[AI in Analytics · Governed AI analytics on BigQuery: who writes the SQL when your team asks in chat · October 9, 2026](/blog/articles/ai-analytics-on-bigquery)

[See all articles →](/blog/articles)

## Book a call

You are booked. The invitation is on its way to , with the calendar invite and the meeting link.

[Reschedule](#)

[Cancel](#)

## Links

Pages this page links to, on this site and on docs.owox.com. Where the page has a Markdown twin, its address follows the link.

- [AI in Analytics](https://www.owox.com/blog/topics/ai) — /blog/topics/ai.md
- [Ievgen Krasovytskyi](https://www.owox.com/team/ievgen-krasovytskyi) — /team/ievgen-krasovytskyi.md
- [how a model invents SQL](https://www.owox.com/blog/articles/ai-analytics-hallucination-deterministic-sql) — /blog/articles/ai-analytics-hallucination-deterministic-sql.md
- [how to connect one](https://www.owox.com/blog/articles/bigquery-mcp-claude) — /blog/articles/bigquery-mcp-claude.md
- [AI assistant](https://www.owox.com/product/ai-assistants) — /product/ai-assistants.md
- [It keeps the request and the SQL, never the rows](https://www.owox.com/blog/articles/can-you-trust-ai-business-numbers) — /blog/articles/can-you-trust-ai-business-numbers.md
- [The job-history route is described here](https://www.owox.com/blog/articles/ai-analytics-on-bigquery) — /blog/articles/ai-analytics-on-bigquery.md
- [Book a Demo](https://www.owox.com/book-a-call) — /book-a-call.md
- [data model](https://www.owox.com/product/data-modeling) — /product/data-modeling.md
- [Why an accuracy score such as 90% says little about one answer](https://www.owox.com/blog/articles/text-to-sql-accuracy-benchmarks-production) — /blog/articles/text-to-sql-accuracy-benchmarks-production.md
- [a trace of a Reddit spend figure](https://www.owox.com/blog/articles/marketing-analytics-data-model) — /blog/articles/marketing-analytics-data-model.md
- [Data lineage](https://www.owox.com/glossary/data-lineage) — /glossary/data-lineage.md
- [This guide](https://www.owox.com/blog/articles/governed-mcp-analytics) — /blog/articles/governed-mcp-analytics.md
- [this one](https://www.owox.com/blog/articles/auditable-analytics-reporting-finance-governance) — /blog/articles/auditable-analytics-reporting-finance-governance.md
- [Get started free](https://www.owox.com/app-signup)
- [AI in Analytics · AI analytics agents replace your backlog, not your analyst · July 2, 2026](https://www.owox.com/blog/articles/ai-analytics-agent-replace-backlog) — /blog/articles/ai-analytics-agent-replace-backlog.md
- [See all articles →](https://www.owox.com/blog/articles) — /blog/articles.md
