Text-to-SQL turns "how many vendors did we onboard last quarter, by region?" into a runnable query — no ticket to the data team, no three-day wait. The habit that makes it safe: read the generated SQL, check its filters, and cross-check one number against a known-good report before anything leaves your screen.
Workflow area: Data & Evidence · Tier: Foundation · Hands-on time: ~25 minutes
Analysts who can pull their own numbers ask ten times more questions, and better ones. Snowflake Cortex, BigQuery's Gemini assistance, and a general LLM given your schema all generate workable SQL from plain English now. The failure mode is not syntax — generated queries almost always run. It is silent semantic error: the wrong date column, a join that duplicates rows, a missing status filter that counts cancelled records. A query that runs and returns a confident wrong number is more dangerous than one that fails, because wrong numbers travel into decks and decisions. Verification is not optional overhead; it is the skill.
Assemble schema context once. Export or copy the relevant table definitions: table names, column names and types, and — critically — the tribal knowledge: which date column means what, what status values exist, known data quirks. If your warehouse has a data catalog or dbt docs, pull descriptions from there. Save this as your standing "schema pack".
Ask with context, and demand explainable SQL. In Snowflake Cortex Analyst or BigQuery's Gemini pane, the schema is already known — go straight to the question. With a general LLM:
You write SQL for analysts. Dialect: [Snowflake / BigQuery /
Postgres].
Schema:
[PASTE TABLE DEFINITIONS + NOTES, e.g. "orders.created_at = order
placed; orders.completed_at = fulfilled; status values: placed,
fulfilled, cancelled, test — EXCLUDE test in all analysis"]
Question: [PLAIN-ENGLISH QUESTION — e.g. "monthly count of new
vendors onboarded in 2025, split by region, excluding rejected
applications"]
Output:
1. THE QUERY — formatted, with a comment on every filter and join
explaining why it is there.
2. ASSUMPTIONS — every choice you made that the question did not
specify (which date column, which statuses included, how ties
or duplicates are handled).
3. SANITY CHECKS — two quick follow-up queries I can run to
validate this result (e.g. total without grouping, count of
excluded rows).
Rules: if the schema does not clearly contain what I asked for,
say so and ask — do not guess column meanings.
Read the SQL before running it. You are not checking syntax — you are checking meaning, and this review is the human gate, not a formality. Four questions: Is it the right date column for what I asked? Are the status/type filters right — what is being silently included or excluded? Could any join multiply rows? Is the grain what I think it is (one row per vendor, or per application)? The ASSUMPTIONS section is where the model confesses; read it every time.
Cross-check against a known-good number. Before using any result, reconcile it once against something already trusted: last month's board pack, a certified dashboard, the ops team's own tracker. Exact match, or an explicable difference ("dashboard includes test records") — either is fine. An unexplained difference stops the work until resolved. A sample verification note worth keeping:
Result: 1,847 vendors onboarded in 2025 H1.
Cross-check: Q1 board pack reports 912 for Q1; my query gives 914
for Q1. Difference: 2 vendors with region NULL, excluded from the
board pack's regional table. Explained. Using 1,847 with note.
Save the question, the SQL, and the verification together. Paste all three into your analysis notes. When the number is challenged in a review — and good numbers get challenged — you reproduce it in one minute. Unreproducible numbers die in meetings, and deserve to.
Query results can contain customer names, financials, and personal data — self-serve only within your warehouse's access controls, never paste result sets containing personal data into external AI tools, and keep exports governed by your data-handling policy.
Text-to-SQL removes the wait, not the responsibility — the analyst who reads the query, checks the filters, and reconciles one number against a trusted source gets the speed and keeps their credibility; the one who forwards the first answer eventually forwards a wrong one.