All articles
ai2026-07-30

How to Write SQL with AI Help — What Actually Speeds You Up, and What Just Looks Like It Does

Contents

Ask AI for a SQL query and fifteen seconds later you have working code. It looks fine, runs without errors, and returns some numbers. The problem is that "working" and "correct" aren't the same thing — and in a data warehouse where the same report gets read by ten people who make decisions based on it, that difference costs you. After a few months of using Cursor and Claude for daily SQL work on a production warehouse in Keboola, I have a fairly concrete picture of where AI genuinely saves me time, and where it only creates the illusion of speed — at the cost of an hour of debugging later.

Where AI genuinely speeds things up

The biggest, most measurable gain is boilerplate and transformations where the logic is simple but the syntax is tedious to write out. A classic example: unnesting nested structures in the GA4 export to BigQuery.

-- Instead of manually writing UNNEST for every event parameter
SELECT
  event_name,
  user_pseudo_id,
  (SELECT value.string_value FROM UNNEST(event_params)
   WHERE key = 'page_location') AS page_location,
  (SELECT value.int_value FROM UNNEST(event_params)
   WHERE key = 'engagement_time_msec') AS engagement_time_msec
FROM `project.analytics_XXXXX.events_*`
WHERE _TABLE_SUFFIX = '20260728'

AI gets this query right on the first try about 95% of the time, because the GA4 export structure is well documented and repetitive. Same goes for window functions for standard tasks — ranking, running totals, period-over-period comparisons. The code is mechanical, the pattern is known, and mistakes are easy to spot because the result either matches or it doesn't.

The second area is translating business logic I already have in my head into syntax I don't remember by heart. I know exactly that I want to calculate cohort retention, but I don't remember whether in Snowflake it's better done via DATEDIFF on months or DATE_TRUNC plus a self-join. AI cuts that research down from ten minutes in the docs to one answer, which I still verify myself.

Third: documentation and comments for existing code. I paste a transformation from Keboola and ask for a description of what each step does — this saves real time during team onboarding, and AI is surprisingly good at it, because it's just reading code linearly.

Where AI only looks faster

The place AI let me down the most was situations requiring context that wasn't in the prompt — and it didn't occur to me to include it. I once asked for a query counting unique buyers month over month. The code was syntactically flawless. Except in our warehouse, one customer_id can have several user_id values after accounts get merged on login, and without that knowledge AI calculated something that looked like retention but was inflated by over ten percent. That's not the model's fault — it's context nobody gave it, context I had in my head and unconsciously assumed was "obvious."

Second problem: performance optimization on large tables. AI can propose a logically correct JOIN, but it doesn't know how clusters are laid out in Snowflake, where the partitions sit, or that the fact_orders table has a billion rows and needs to be filtered by order_date before the join, not after. I once got a query that returned the correct result but scanned the entire fact table instead of leveraging date as a clustering key — on a small sample you don't see the difference; in production it was the difference between 3 seconds and 40.

-- AI-generated: logically fine, performance-poor
SELECT o.order_id, o.customer_id, SUM(oi.line_total)
FROM fact_orders o
JOIN fact_order_items oi ON o.order_id = oi.order_id
WHERE o.order_date >= '2026-07-01'
GROUP BY 1, 2

-- After the fix: the filter on the clustering key hits both tables
-- and limits the scan before the join, not after
SELECT o.order_id, o.customer_id, SUM(oi.line_total)
FROM fact_orders o
JOIN fact_order_items oi
  ON o.order_id = oi.order_id
  AND oi.order_date >= '2026-07-01'
WHERE o.order_date >= '2026-07-01'
GROUP BY 1, 2

Third: situations where a query needs to handle edge cases specific to our own data that AI simply has no way of knowing — like purchase events sometimes duplicating on frontend retries, requiring deduplication by transaction_id rather than event_timestamp.

The test I run before I trust generated SQL

I don't read generated code line by line hunting for typos — that's pointless, since it's almost always syntactically fine. Instead I check three things:

  1. Row count before and after every join. If a join increases row count somewhere I didn't expect, there's key duplication AI wasn't aware of.
  2. The result against a known edge case. I pick one specific customer or order I know from memory and check by hand whether the number matches.
  3. Explain plan or query profile — in Snowflake I check whether the query is actually using partitions/clusters before I run it against the full production table.

This three-minute checklist has caught more errors for me than an hour of reading code.

A prompt is not a spec

The biggest shift in how I work now: I stopped treating the first prompt as something meant to deliver a finished result. I treat it as a first iteration, to which I add the context the model couldn't have known — key structure, known edge cases, data volume. The more of that context I front-load (schema, sample rows, known data pitfalls), the less I have to fix afterward. AI doesn't shorten the thinking about the problem — it shortens the time it takes to write that thinking down in syntax.

TL;DR

  • AI genuinely speeds things up for: boilerplate (UNNEST, window functions), translating known logic into unfamiliar syntax, and documenting existing code.
  • AI only looks faster where business or data-structure context is needed but missing from the prompt — key duplication, merged accounts, data-specific edge cases.
  • Performance optimization (clusters, partitions, filter order) is still a domain where you need to know how the warehouse is physically laid out — AI can't see that.
  • Check row counts before/after joins, test against a known edge case, look at the query profile — faster than reading code line by line.
  • The more context (schema, edge cases, data volume) you front-load into the first prompt, the fewer fixes you'll need later — a prompt is a starting point, not a spec for a finished solution.

Want to put this into practice?

Let's talk about your data and where to start. The first call is free.

Book a consultation

More articles about data analytics:

Back to blog