Window functions

Percent of total (and percent of group)

2 min · updated June 16, 2026

Divide each row by a windowed SUM. An empty OVER () is the grand total; OVER (PARTITION BY ...) is the group total. Same syntax in every dialect.

SELECT
  category,
  amount,
  amount * 100.0 / SUM(amount) OVER ()                      AS pct_of_grand_total,
  amount * 100.0 / SUM(amount) OVER (PARTITION BY category) AS pct_of_category
FROM sales;

Integer-division trap. In PostgreSQL, MySQL and SQLite, amount / SUM(...) with two integer columns does integer division and returns 0 for every fraction. Multiply by 100.0 (or cast one side to a decimal/float) before dividing, as above. BigQuery, Snowflake and DuckDB divide as floats by default, but * 100.0 is harmless and keeps the query portable.

Round it for display:

SELECT
  category, amount,
  ROUND(amount * 100.0 / SUM(amount) OVER (), 1) AS pct
FROM sales;

Works in MySQL 8+, PostgreSQL, SQLite 3.25+, BigQuery, Snowflake and DuckDB.

← All recipes