data-question
Data Question
Use the available read-only tools to answer the user's question. Source databases and project files stay unchanged; when exposed, sql_materialize may create session-local tables in the scratch warehouse. All examples below use synthetic tables. Adapt names and dialects after inspection. This skill is self-contained.
Workflow
- Inspect. Use
warehouse_list,schema_inspectand smallsql_executequeries as needed. Inspect actual keys and text before choosing joins, casts or parsing rules: schemas alone hide whitespace, case, prefixes and mixed formats. Preserve meaningful leading zeros; check that normalization does not merge distinct identities. - Plan. State the population, row grain, denominator, units and material assumptions. Decide which joins and aggregation levels preserve them. Keep this brief; a trivial lookup does not need a checklist or several validation scans.
- Compute in-engine. Filter and aggregate close to the source. Derive large intermediate sets with joins/CTEs or the scratch bridge below, rather than copying rows into
IN (...)orVALUES. Small user-supplied constants are fine. Keep LIMIT, sampling and approximate functions exploratory unless the user requests an estimate. For exact final answers, aggregate the full intended population in SQL. - Verify relevant invariants. Check key uniqueness, before/after join counts, missing matches and null share when they affect the answer. Use
sql_checkfor these invariants and extraction coverage; for cross-warehouse comparisons, first materialize both sides intoscratchwithsql_materialize. Reconcile components with totals and preserve weighting.SUM(group_mean * contributing_count) / SUM(contributing_count)recovers the overall mean for disjoint, complete groups using unrounded means and counts of the same non-null measure;AVG(group_mean)gives each group equal weight.sql_analyzeis optional. If available, a read-onlydata-explorerviataskcan independently re-derive a difficult result. - Answer. Explain the basis in one or two sentences (population, grain, caveats), retaining useful tables or explanation before it. Finish with
**Answer:** <requested value(s), with units>. If evidence or available tools are insufficient, finish with**Answer:** unable to determine — <why>. Never guess a missing result.
Select needed columns and useful partition filters to control cost; LIMIT need not reduce scanned bytes. Report measured costs, not invented estimates. After a timeout, revise the query or split work along exhaustive, disjoint partitions; a failed query is not a zero count.
Cross-engine bridge
Prerequisites: both source warehouses are connected; scratch is available and uses DuckDB; sql_materialize is exposed. Source queries use their own engine's dialect. The synthetic source tables here are orders(order_id, customer_code, amount, status) on sales_db and customers(customer_code, region) on crm_db, with text customer codes.
After inspecting examples and checking normalization collisions, invoke sql_materialize twice: