Back to Blog

Why Your AI's Join Returns the Wrong ID

Asked for orders with customer names and the id column is the customer id — or both tables' ids mashed together. SELECT * after a JOIN produces two columns named id. The model often picks the wrong one for a follow-up filter.

You ask for "recent orders with the customer name." The table looks fine. You say "show me order 1842." The AI filters WHERE id = 1842 and returns a customer, or nothing, or the wrong order. Both tables have a column named id. After SELECT *, the result has two of them. Something in the pipeline kept one.

Two columns, one label

SELECT *
FROM orders o
JOIN customers c ON c.id = o.customer_id

The result set includes o.id and c.id. Many drivers and chat renderers expose a single id — usually the last one wins, or the first. The model then talks about "id 1842" as if there were one.

SELECT
  o.id AS order_id,
  o.created_at,
  o.amount,
  c.id AS customer_id,
  c.name
FROM orders o
JOIN customers c ON c.id = o.customer_id

Now "order 1842" has a name. A follow-up WHERE o.id = 1842 cannot mean the customer.

This is not fan-out (too many rows) and not latest-row (wrong sibling columns). The row count can be perfect. The identifier is just the other table's.

How to catch it

If a follow-up by id looks insane, ask:

List the column names in the last result, including table aliases.
Which id is the order? Which is the customer?
Re-run with o.id AS order_id, c.id AS customer_id. No SELECT *.

describe_table on both tables before the join would have shown two ids — the same habit as don't guess column names.

The prompt that heads this off

After any JOIN, don't SELECT *. Alias every id: table_id.
Never filter on a bare id when two tables are in scope — use
orders.id or the alias. If I say "that id," confirm which table.

The short version

id after a join is not a unique idea. It's two columns wearing the same name. If "open this order" loads a customer, the model kept the wrong id.


Read-only MCP gateway: mcpserver.design.

Related reading: