DEV Community

Cover image for SQL Pattern Series #15: The Percent-of-Total Pattern
Baldwin Apps
Baldwin Apps

Posted on

SQL Pattern Series #15: The Percent-of-Total Pattern

Seeing each value's contribution to the whole

SQL Pattern Series #15 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:

  • How to calculate percentages without a self-join
  • How window functions simplify percent-of-total calculations
  • Why percentages often communicate better than raw numbers
  • When to use the Percent-of-Total Pattern

Raw numbers are useful.

But sometimes the more important question is:

How much of the total does this represent?

For example:

  • What percentage of sales comes from each product category?
  • What percentage of revenue comes from each region?
  • What percentage of support tickets belong to each team?
  • What percentage of traffic comes from each source?

That is where the Percent-of-Total Pattern becomes useful.


The Problem

Imagine a sales table:

Category Sales
Hardware 5000
Software 3000
Services 2000

The total sales are:

10000
Enter fullscreen mode Exit fullscreen mode

But the raw numbers do not immediately show each category's contribution.

We often want to see:

Category Percent
Hardware 50%
Software 30%
Services 20%

That requires comparing each value to the overall total.



The Percent-of-Total Pattern

A common solution uses a window aggregate:

SUM(column) OVER ()
Enter fullscreen mode Exit fullscreen mode

This calculates the grand total while still preserving individual rows.

The pattern is:

column /
SUM(column) OVER ()
Enter fullscreen mode Exit fullscreen mode

Each row divides itself by the overall total.


Example

SELECT
    Category,
    Sales,
    Sales * 1.0
        / SUM(Sales) OVER ()
        AS PercentOfTotal
FROM SalesData;
Enter fullscreen mode Exit fullscreen mode

This query calculates the total sales once and makes that value available to every row.

Each row then computes its own percentage.


Example Result

Category Sales PercentOfTotal
Hardware 5000 0.50
Software 3000 0.30
Services 2000 0.20

To display percentages:

ROUND(
    Sales * 100.0
    / SUM(Sales) OVER (),
    2
) AS PercentOfTotal
Enter fullscreen mode Exit fullscreen mode

Result:

Category PercentOfTotal
Hardware 50.00
Software 30.00
Services 20.00

Why This Pattern Matters

Humans are often better at understanding proportions than raw counts.

Consider:

Category A: 5,000
Category B: 3,000
Category C: 2,000
Enter fullscreen mode Exit fullscreen mode

versus:

Category A: 50%
Category B: 30%
Category C: 20%
Enter fullscreen mode Exit fullscreen mode

The percentages immediately communicate relative importance.


Window Functions Make This Easy

Before window functions became widely available, developers often solved this problem using:

SELECT
    Category,
    Sales,
    Sales /
    (
        SELECT SUM(Sales)
        FROM SalesData
    )
FROM SalesData;
Enter fullscreen mode Exit fullscreen mode

That approach works.

But window functions often make the intent clearer because both the row value and the total remain visible in the same query.


Percent of Total Within Groups

Sometimes you want percentages inside groups rather than across the entire table.

For example:

What percentage of regional sales comes from each product?

You can partition the total:

SUM(Sales) OVER (
    PARTITION BY Region
)
Enter fullscreen mode Exit fullscreen mode

Now each region receives its own denominator.

The same pattern applies:

Sales /
SUM(Sales) OVER (
    PARTITION BY Region
)
Enter fullscreen mode Exit fullscreen mode

A Note on Integer Division

One common mistake is:

Sales /
SUM(Sales) OVER ()
Enter fullscreen mode Exit fullscreen mode

If both values are integers, some databases may perform integer division.

To avoid this, force decimal math:

Sales * 1.0
Enter fullscreen mode Exit fullscreen mode

or:

CAST(Sales AS DECIMAL(10,2))
Enter fullscreen mode Exit fullscreen mode

The exact syntax varies by database system.


When I Reach for This Pattern

I typically use the Percent-of-Total Pattern when:

  • comparing contributions
  • building dashboards
  • analyzing revenue distribution
  • measuring category importance
  • presenting executive summaries

Examples include:

  • sales by category
  • revenue by region
  • tickets by department
  • users by platform
  • expenses by cost center

Key Takeaway

Raw numbers tell you how much.

Percentages tell you how important.

The Percent-of-Total Pattern helps answer:

What share of the whole does this represent?

Sometimes contribution matters more than magnitude.


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 Bubble Pop

If you are learning SQL or helping others learn SQL, 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)