Code-as-Documentation: An SQL Development Paradigm for the AI Era

A “runnable but unmaintainable” SQL query

Let’s first look at the following SQL used in a production environment. The query aims to “merge all overlapping time intervals within each account”:

SELECT account_id, MIN(start_date) AS start_date, MAX(end_date) AS end_date
FROM (
  SELECT account_id, start_date, end_date, prev_max,
    SUM(CASE WHEN start_date > prev_max OR prev_max IS NULL THEN 1 ELSE 0 END) 
      OVER (PARTITION BY account_id ORDER BY start_date) AS gid
  FROM (
    SELECT account_id, start_date, end_date,
      MAX(end_date) OVER (
        PARTITION BY account_id 
        ORDER BY CASE WHEN account_id IS NOT NULL THEN 1 END, start_date
        ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
      ) AS prev_max
    FROM acc
  ) t1
) t2
GROUP BY account_id, gid

This SQL snippet uses window functions MAX()OVER and SUM() OVER for their cumulative-sum technique, along with ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING – syntax most developers would probably need to look up in the documentation. The syntax is completely correct, and the query runs and produces the expected output.

Six months later, the requirement changes – the merging condition shifts from “overlapping alone” to “intervals of no more than 3 days”. Modifying the code to fit this new rule is extremely difficult, basically amounting to a rewrite. You’d need to work out the logic from scratch, mentally re-running the window functions’ computations, just to figure out what to change and how. The code runs, but the cost of understanding it is about the same as rewriting it from scratch.

This is the reality of SQL development: code is written for machines to execute, not for humans to read.

Why self-documentation is particularly hard for SQL

SQL is a declarative language: it tells the database what to do, not how to do. This creates a problem – business logic is encoded into the syntactic structure instead of being expressed explicitly.

  • A window function like LAG(amount, 1) OVER (PARTITION BY customer_id ORDER BY month) may correspond to the business concept of “calculating last month’s transaction amount”.

  • A cumulative-sum snippet like SUM(CASE WHEN ... THEN 1 ELSE 0 END) OVER (...) may correspond to the logic of “conditional segmentation”.

  • But these business semantics are implicit in SQL – readers need to infer for themselves what each snippet is actually doing.

Even worse, comments cannot solve this problem. Code changes, but comments don’t always follow. Over time, comments become less reliable than the code itself. And SQL’s nested structure is inherently resistant to comments. Wedged between multiple layers of parentheses, they only make readability worse.

AI-assisted coding doesn’t solve this problem either. You generate a SQL snippet with AI, execute and commit it – but you don’t put the prompts in the repository. All that’s left is the final SQL. When the requirement changes, you are back to the same SQL, and have to re-decode its logic from scratch. Even if the original spec written for AI is kept, there’s no guarantee the regeneration produces the same SQL – LLMs aren’t deterministic. Update the spec and regenerate, and you might get a completely different query, which means a re-audit is involved. That’s not a modification, that amounts to a rewrite.

Therefore, AI-assisted coding doesn’t solve the root problem: documentation and code falling out of sync.

Unless, spec and SQL are fused into one – permanently paired, so a spec change automatically updates the SQL.

“Code as documentation” is an ideal. SQL makes it further out of reach.

One misconception needs clearing up here: “code as documentation” doesn’t mean “writing lots of comments in the code”. Comments are a supplement. True “code as documentation” means three things:

  1. The code structure itself expresses the logic. Reading the code is as clear as reading documentation – no extra explanation needed.

  2. Code and documentation are the same thing. There’s no such problem as “the code changed but the documentation didn’t”.

  3. When new hires take over, reading the code is enough to understand the business logic – no extra training and verbal handoffs from the last person needed.

In the SQL world, this means SQL itself needs to be self-descriptive. Every line of code should tell the reader clearly “what this step is doing”, not “what this syntax does”. But native SQL can’t do this. Multi-layer nesting is everywhere, and readability suffers badly.

So, the solution is this: make the spec both readable and executable. Spec is documentation; spec is code.

SQLazy’s solution: workflow as documentation

Here’s what SQLazy does: skip writing SQL directly. Instead, describe the logic as a workflow of steps. Each step is an atomic action. The steps combined are the complete business logic.

Take the example of “merging overlapping intervals” again. Here’s how SQLazy’s workflow expresses it:

Step

Action and Description

1

sort account_id, start_date

2

compute end_date[:-1] max as prev_max

3

segment condition start_date > prev_max as gid

4

summarize start_date min, end_date max

These lines of workflow read almost like natural language: sort, calculate the maximum end date so far, segment rows by condition, aggregate to get the earliest and latest dates. You can guess what most actions mean without ever having to learn them. Only “segment” needs a bit of explanation – it means “group the data by condition”. But paired with the visual step-by-step execution, one glance at the intermediate result makes it click instantly.

..

Run this example online: https://www.sqlazy.com/?4Bs

This compilable workflow is itself the documentation:

  • Every step has clear business meaning: “sort” sorts, “compute” calculates helper values, “segment” groups the data by condition, and “summarize” aggregates.

  • The order of steps is the order of thinking. First sort, then compute, then segment, then aggregate – exactly how you’d work through this problem manually.

  • No extra comments are needed to explain “what this SQL is doing”. Every line of the workflow already says it clearly.

  • Six months later, when the requirement changes, just open the workflow and edit the corresponding step directly.

Code and documentation are one thing, not two. This is “code-as-documentation” actually made real.

Here’s another example: group by account, and reset the sequence number whenever the interval between activities exceeds one hour. Here’s how SQLazy’s workflow expresses it:

Value

Anchor

Statement

t2

numEvents

sort account_number asc, dt asc

t3


segment condition ((dt[-1] elapse 3600 second)<= dt) partition account_number as grp



compute # as seq partition account_number, grp

Three lines of workflow, business logic clear at a glance: “reset the sequence number whenever the interval exceeds one hour”. The equivalent hand-written SQL needs at least two layers of nested window functions, plus LAG-based time-gap calculations. With the workflow, you don’t need to take care of how the SQL is written – the compiler handles that for you.

The compiler guarantees: documentation and code will never get out of sync

Under the traditional model, documentation and code are separate, kept in sync only by hand – and manual sync is error-prone. Documentation gets written, then the code changes without the docs catching up; or the code changes but the documentation isn’t updated.

SQLazy’s model is this: workflow (documentation) → compiler → SQL (code).

Compile the workflow above into SQL (switchable across different databases):

..

Documentation is the source. Code is the compiled output. As long as the workflow stays the same, the generated SQL stays the same; when the workflow changes, the SQL regenerates automatically. There’s no more “documentation changed but code didn’t” or “code changed but documentation didn’t” – because they’re two sides of the same thing.

When you switch databases, just change the target option – from MySQL to Oracle or from PostgreSQL to Snowflake – and the compiler automatically generates SQL in the matching dialect. No need to modify the workflow. No need to rewrite the documentation.

In the SQL world, “Code-as-documentation” has always been a hard-to-reach ideal. Without a workflow mechanism like SQLazy’s, code and documentation stay two separate things. You write the SQL, then have to write separate documentation explaining what it does. Syncing the two falls entirely on manual work – and manual work means errors.

SQLazy changes that. It breaks complex SQL into clear steps, which themselves are the documentation, and the compiler guarantees code and documentation stay in sync, permanently.

This isn’t wrapping a shell around SQL. It’s changing the development paradigm from “writing code for machines to read” to “writing logic for humans to read and letting the machine translate it”. The workflow is for humans. The SQL is for the database to run. The compiler keeps the two in sync – no manual work required.

Next time you open a SQL file written three months ago and can’t make sense of it, ask yourself: if you’d written it as a workflow instead, would you still be in this much pain?