DEV Community

Cover image for SQL Pattern Series #17: The Reusable Logic Pattern
Baldwin Apps
Baldwin Apps

Posted on

SQL Pattern Series #17: The Reusable Logic Pattern

Building the logic once so the final query is easier to read

SQL Pattern Series #17 of 21

A collection of practical SQL patterns that help developers recognize common solutions to recurring database problems.

What You'll Learn

In this article you'll learn:

  • What a CTE is
  • How WITH can make query logic easier to read
  • Why reusable logic helps reduce complexity
  • When to use the Reusable Logic Pattern

Some SQL queries become difficult to read because they try to do everything at once.

They calculate values.

Filter rows.

Group data.

Join tables.

Apply business rules.

Return results.

All in one long statement.

That can work.

But it can also become difficult to understand.

That is where the Reusable Logic Pattern becomes useful.


The Problem

Imagine you need to calculate total revenue by customer, then return only customers whose revenue exceeds a threshold.

You could write the logic as a nested subquery.

But as the query grows, the structure becomes harder to follow.

The issue is not always the SQL itself.

Sometimes the issue is that the logic needs a name.



The Reusable Logic Pattern

The Reusable Logic Pattern uses a common table expression, or CTE, to name an intermediate result.

The general form is:

WITH cte_name AS (
    SELECT ...
)
SELECT ...
FROM cte_name;
Enter fullscreen mode Exit fullscreen mode

A CTE lets you build a piece of logic once, give it a meaningful name, and query it in the final statement.


Example

WITH RevenueByCustomer AS (
    SELECT
        CustomerID,
        SUM(Amount) AS TotalRevenue
    FROM Orders
    GROUP BY CustomerID
)
SELECT
    CustomerID,
    TotalRevenue
FROM RevenueByCustomer
WHERE TotalRevenue > 1000;
Enter fullscreen mode Exit fullscreen mode

The first part calculates revenue by customer.

The final query filters the result.

The logic now has a name:

RevenueByCustomer
Enter fullscreen mode Exit fullscreen mode

That name makes the query easier to understand.


Why This Pattern Matters

CTEs can make complex queries easier to read by separating steps.

Instead of forcing the reader to understand everything at once, the query can be read in stages.

For example:

  1. Build revenue by customer.
  2. Query the result.
  3. Apply a final filter.

That structure reduces cognitive load.

It also makes the query easier to debug.


CTEs Are Not Tables

A CTE may look like a temporary table, but it is not necessarily stored as one.

It is a named query expression available to the statement that follows it.

The database optimizer decides how to process it.

That means a CTE is usually best understood as a readability and structure tool, not automatically as a performance tool.


Naming the Logic

The most valuable part of a CTE is often the name.

Compare this:

WITH x AS (
    SELECT ...
)
Enter fullscreen mode Exit fullscreen mode

to this:

WITH RevenueByCustomer AS (
    SELECT ...
)
Enter fullscreen mode Exit fullscreen mode

The second version tells the reader what the intermediate result represents.

Good names help turn query structure into documentation.


Multiple CTEs

You can often use more than one CTE to build a query in steps.

WITH RevenueByCustomer AS (
    SELECT
        CustomerID,
        SUM(Amount) AS TotalRevenue
    FROM Orders
    GROUP BY CustomerID
),
HighValueCustomers AS (
    SELECT
        CustomerID,
        TotalRevenue
    FROM RevenueByCustomer
    WHERE TotalRevenue > 1000
)
SELECT *
FROM HighValueCustomers;
Enter fullscreen mode Exit fullscreen mode

This can make multi-step logic easier to follow.

Each CTE represents one stage of the process.


A Note on Database Differences

CTEs are widely supported, but behavior can vary between database systems.

Some databases may inline CTEs.

Some may materialize them in certain situations.

Some support recursive CTEs.

Some have optimizer rules that affect performance.

The syntax is broadly familiar, but always validate performance and behavior in your specific database system.


When I Reach for This Pattern

I typically use the Reusable Logic Pattern when:

  • a query has multiple logical steps
  • nested subqueries are becoming hard to read
  • intermediate results need meaningful names
  • the same derived logic is referenced later
  • I want the query to be easier to debug

Examples include:

  • revenue by customer
  • filtered account groups
  • staged reporting logic
  • pre-aggregated data
  • multi-step analytics queries

Key Takeaway

Complex SQL becomes easier when each part has a clear job.

The Reusable Logic Pattern helps answer:

Can I name this piece of logic?

A CTE lets you build the logic once and query it clearly.

Sometimes the best improvement is not a shorter query.

It is a query that explains itself.


SQL Pattern Series

This article is part of the SQL Pattern Series, a collection of practical SQL patterns that help developers recognize common problem-solving approaches found in reporting, analytics, and application development.

Previous articles:

  • SQL Pattern Series #1: The Presence Pattern
  • SQL Pattern Series #2: The Match Pattern
  • SQL Pattern Series #3: The Missing Data Pattern
  • SQL Pattern Series #4: The Moving Sum Pattern
  • SQL Pattern Series #5: The Deduplication Pattern
  • SQL Pattern Series #6: The Routing Pattern
  • SQL Pattern Series #7: The Running Total Pattern
  • SQL Pattern Series #8: The Query Order Pattern
  • SQL Pattern Series #9: The Period-over-Period Pattern
  • SQL Pattern Series #10: The Hierarchy Pattern
  • SQL Pattern Series #11: The Merge Pattern
  • SQL Pattern Series #12: The Fallback Pattern
  • SQL Pattern Series #13: The Gap Detection Pattern
  • SQL Pattern Series #14: The Top-Per-Group Pattern
  • SQL Pattern Series #15: The Percent-of-Total Pattern
  • SQL Pattern Series #16: The Missing Match Pattern

SQL Bubble Pop

I created SQL Bubble Pop, a mobile game that teaches SQL concepts through quick, interactive challenges and pattern recognition exercises.

The goal is simple:

Learn SQL by recognizing patterns instead of memorizing syntax.

Top comments (0)