---
title: "Why Your AI Tool Picks the Wrong Column"
description: "A tool that answers confidently and wrongly is usually missing semantic context. How column descriptions, key tables, and join paths change the SQL that gets generated."
canonical: https://datarelix.ai/resources/guides/why-semantic-context-matters/
publishDate: 2026-08-13
updatedDate: 2026-08-17
lastVerified: 2026-08-17
---

# Why Your AI Tool Picks the Wrong Column

When an AI tool filters on the wrong column, the usual cause is missing **semantic context** rather than a weak model. **Schema structure** tells it that a column called `status` exists and holds text. It does not say that `'completed'` means paid and shipped, that `'closed'` was the pre-2024 spelling of the same thing, or that `orders_v2` is the live table and `orders` is an abandoned migration. That missing layer is what separates a tool that works on your data from one that writes fluent SQL against the wrong column.

## If you have seen this happen

Anyone who has connected a natural-language analytics tool, watched it answer a question confidently and incorrectly, and wondered whether the model is bad. Usually it is not. Also for analytics engineers deciding how much curation is worth doing before rolling a tool out.

## The two layers, and which one you control

<figure>
  <img
    src="/images/guides/semantic-context-layers.svg"
    alt="Diagram showing three kinds of information in a database and what crosses a context boundary. Structure — names, types, primary keys, declared foreign keys — is read automatically and crosses. Curated meaning — descriptions, marked key tables, corrected relationships, excluded columns — is added by your team and crosses. Row values are not part of schema context, with a noted exception for single-row answer values carrying into follow-up questions."
    width="900"
    height="470"
    loading="lazy"
    decoding="async"
  />
  <figcaption>Structure is free and automatic. Meaning is the part you supply, and the part that decides answer quality.</figcaption>
</figure>

### Layer one: structure, which you get for free

Introspection reads table and column names, data types, primary keys, declared foreign keys, and nullability without anyone doing anything. Every tool in this category reads it, so it is **not** where quality differences between tools come from.

### Layer two: meaning, which you have to supply

Databases mostly do not store meaning. It lives in a wiki, a dbt `description:` field nobody filled in, or an analyst's memory. When it is absent, the model does what any competent stranger would do with your schema: it guesses from names.

## What ambiguity costs

These are the failure shapes that recur:

| Ambiguity | What the model does without context | What one line of context fixes |
|---|---|---|
| **Status codes** | Filters on the value that sounds right, or omits the filter entirely | `status`: order lifecycle — `'completed'` means paid and shipped; use for revenue |
| **Multiple amount columns** | Picks `amount` over `net_amount` because the name is simpler | `amount`: gross, before refunds. Use `net_amount` for reported revenue |
| **Deprecated tables** | Queries the table with the cleaner name | `orders`: superseded 2024-03; use `orders_v2` |
| **Test and internal rows** | Counts them | `customers`: includes internal test accounts where `is_internal = true` — exclude for reporting |
| **Undeclared join paths** | Infers a join from naming convention; sometimes wrong | Declare the relationship, or correct the inferred one |
| **Grain confusion** | Sums a column that is already an aggregate | `daily_revenue`: pre-aggregated per day — do not sum across the same day |
| **Timezone-mixed timestamps** | Compares fields stored in different zones | `created_at`: UTC. `local_ordered_at`: store-local, not comparable |

None of these are model failures. Each is a question the schema does not answer, resolved by the model committing to one reading.

### What one line of context actually changes

Take the first row. The question is "what was revenue last month?", against a fictional retailer's
demo schema where `orders.status` holds `'completed'`, `'pending'`, and `'cancelled'`.

With no description on `status`, nothing in the schema says cancelled orders are not revenue, so
nothing filters them out:

```sql
SELECT SUM(amount) AS revenue
FROM orders
WHERE ordered_at >= date_trunc('month', now() - interval '1 month')
  AND ordered_at <  date_trunc('month', now());
```

Now add one line of context to `status`: *order lifecycle; `'completed'` means paid and shipped, use
it for revenue.* The same question now produces:

```sql
SELECT SUM(amount) AS revenue
FROM orders
WHERE ordered_at >= date_trunc('month', now() - interval '1 month')
  AND ordered_at <  date_trunc('month', now())
  AND status = 'completed';
```

Both queries are valid SQL and both run without error. The first one silently includes cancelled
orders, so it reports a higher number — and nothing about the answer looks wrong. That is the whole
argument for curation: the cost of missing context is not a failure, it is a plausible number.

## What to describe first: curation in priority order

Describing everything is how curation projects stall. Rank instead:

1. **Every column you would filter on.** Status, type, category, flag columns — these decide which rows are counted.
2. **Every column with a sibling.** `amount` and `net_amount`, `created_at` and `updated_at`, `user_id` and `account_id`. Ambiguity between near-identical columns is the most expensive kind.
3. **Deprecated or shadowed tables.** One line saying "do not use this" prevents a whole class of wrong answers.
4. **Join paths that are not declared as foreign keys.** Especially in warehouses like Snowflake where keys are informational and often never declared at all — covered in [ask Snowflake questions in plain English](/resources/guides/natural-language-analytics-for-snowflake/).
5. **Mark your key tables.** Fact tables and core dimensions. When a schema is large enough that context has to be truncated, marked tables survive the cut, so the model keeps the ones that matter.

Everything else can wait. An auto-generated description is a starting draft, not a finished one: where it only restates the column name, it adds nothing the model could not already read. The value comes from editing the columns in the list above.

## Curation is not a semantic-layer project

A common objection: "this is just building a semantic layer with extra steps." A semantic layer **computes** metrics — it owns the definition of revenue and produces it consistently. Semantic context **describes** what already exists so a query can be written correctly against it. If you have a semantic layer, keep it; the best configuration is to point the conversational tool at the marts your semantic layer produces, so questions inherit definitions instead of re-deriving them. That is the setup argued for in [building self-service analytics without replacing your stack](/resources/guides/self-service-analytics-without-replacing-your-stack/).

If you do not have one, curation is not a substitute — but it is cheaper: describing the columns you filter on is a per-schema task, not a modelling project.

## Context governance: keeping it true

Descriptions rot faster than schemas do, and a confidently wrong description is worse than none: it converts a coin-flip into a reliable error.

- **Keep a reviewed source of truth.** Descriptions you enter in a tool are easy to change and easy to forget. Keep the canonical wording where your models are reviewed — a dbt `description:`, a `COMMENT ON`, a file in the repo — so a change is visible to the team, and re-apply it when the schema moves. Datarelix does not import existing database comments or dbt descriptions today; descriptions are entered against the connection.
- **Re-check on schema change.** A renamed column with a stale description is the worst case.
- **Watch for contradiction.** When a generated query filters on something that surprises you, the description is usually the thing that is wrong.
- **Give ownership per schema.** Without a named owner, descriptions stop being updated when the schema changes.
- **Verify against known answers periodically.** Ask questions whose answers you already know; the point of an evidence trail is that drift is visible — the routine is in [how to verify an AI-generated data answer](/resources/guides/verify-ai-data-answers/).

## Curating context in Datarelix

When you connect a database, Datarelix introspects structure directly — tables, columns, types, primary keys, declared foreign keys, nullability. An optional **AI schema analysis** (metered per month — see [pricing](/pricing/)) then proposes **descriptions** and infers relationships from naming conventions where foreign keys were never declared. It works from schema structure only; it is not shown sample rows.

Everything it proposes is editable, which matters because inference is sometimes wrong. On the schema page you can rewrite descriptions, mark tables as key tables, correct or dismiss inferred relationships, override primary keys, and exclude columns from context entirely. Very large schemas do not fit in a single request, so the context is trimmed — tables you mark as key tables are kept.

The resulting context is what accompanies each question, alongside the question itself. Rows are not part of it, with one honest exception: a **single-row answer value** can carry into follow-up conversation context so that "and how does that compare to last year?" resolves. Result tables do not. "Never your data" would therefore be an overstatement, which is why this guide does not make it. The full pipeline is in [text-to-SQL explained](/resources/guides/text-to-sql-explained/), and the credential side is in [how credentials stay out of the model](/resources/guides/credentials-away-from-the-model/).

## What curation cannot fix

Curation raises the floor; it does not make interpretation deterministic. An ambiguous question over a perfectly described schema is still ambiguous — "top customers" can still mean revenue or order count — which is why the query is shown with every answer rather than hidden behind confidence language.

Descriptions cannot repair a genuinely broken model. If two tables disagree about what a customer is, no amount of prose reconciles them; that is a modelling fix. Very large schemas will be truncated no matter how well described, so scoping a connection to the schema that matters beats describing everything. And inferred relationships are hypotheses — check the joins in early answers before trusting a number, especially on schemas you did not model yourself.

## Notes on the examples

Product statements describe Datarelix as shipped in August 2026 — including the deliberate disclosure that single-row scalars can enter follow-up context, which is stated here because the alternative absolute would be false. The [security page](/security/) states the execution boundaries canonically. Example descriptions use a fictional retailer's schema and are illustrative. The ambiguity table is drawn from recurring patterns in production schemas, not from a published study; it is offered as a checklist rather than a measured ranking.

## Describe ten columns and re-ask

Pick your busiest schema and describe the ten columns you filter on most. Then follow the [quickstart](https://docs.datarelix.ai/quickstart/), ask five questions you know the answers to, and read the `WHERE` clauses. Your first 14 days run at Pro limits, no credit card required.
