Skip to content
Home » Comprehensive Guide to SQL Window Functions

Comprehensive Guide to SQL Window Functions

SQL, the language that reigns supreme in the world of relational databases, offers an array of features to manipulate and analyze data effectively. A notably powerful feature among them is the SQL window functions. Window functions enable computations across a set of rows related to the current row, thus bringing a whole new level of analytical capability to your data operations. This article will take you through the essential aspects of SQL window functions, illustrated with code snippets and their results.

Understanding SQL Window Functions

Unlike other SQL functions that return a single result per group of rows, window functions return a single result for each row from the query, and the result is somehow related to a ‘window’ of rows around the current row. A window function call always contains an OVER clause, distinguishing it from other function calls.

Here is the basic syntax of a window function:

function_name (expression) OVER (
    [PARTITION BY column_name]
    [ORDER BY column_name [ASC | DESC] [NULLS {FIRST | LAST}]]
    [ROWS | RANGE window_frame]
)
SQL

In this syntax, the function_name can be any aggregate function such as ROW_NUMBER(), RANK(), DENSE_RANK(), SUM(), AVG(), MAX(), MIN(), and COUNT(). The expression is often a column or columns.

The PARTITION BY clause, which is optional, divides the result set into partitions (akin to subsets), over which the window function is applied. The ORDER BY clause sorts rows within each partition. The window_frame clause specifies the set of rows included in the computation within a partition.

SQL Window Functions in Action

Let’s utilize the following “sales” table for our examples:

idproductsales_amount
1A100
2B200
3C150
4A200
5B200
6C350
7A100
8B400
9C150

ROW_NUMBER()

ROW_NUMBER() assigns a unique row number to each row in the result set.

SELECT product, sales_amount,
ROW_NUMBER() OVER (ORDER BY sales_amount) AS row_number
FROM sales;
SQL

Result:

productsales_amountrow_number
A1001
A1002
C1503
C1504
B2005
A2006
B2007
C3508
B4009

RANK() and DENSE_RANK()

RANK() and DENSE_RANK() assign a unique rank to each distinct row within a partition.

SELECT product, sales_amount,
RANK() OVER (ORDER BY sales_amount) AS rank,
DENSE_RANK() OVER (ORDER BY sales_amount) AS dense_rank
FROM sales;
SQL

Result:

productsales_amountrankdense_rank
A10011
A10011
C15032
C15032
B20053
A20053
B20053
C35084
B40095

The RANK() function in SQL assigns a unique rank within the ordered partition for each row, starting at 1 for the first row in each partition. When two (or more) rows have the same values, they receive the same rank. However, RANK() will skip the next rank(s) in the sequence for the subsequent row(s). Use DENSE_RANK() if you don’t want  sequences to be skipped in case of ties.

SUM(), AVG(), MAX(), MIN(), and COUNT()

Aggregate functions such as SUM(), AVG(), MAX(), MIN(), and COUNT() can also serve as window functions.

SELECT product, sales_amount,
SUM(sales_amount) OVER (PARTITION BY product) AS product_total,
AVG(sales_amount) OVER (PARTITION BY product) AS product_avg,
MAX(sales_amount) OVER (PARTITION BY product) AS product_max,
MIN(sales_amount) OVER (PARTITION BY product) AS product_min,
COUNT(*) OVER (PARTITION BY product) AS product_count
FROM sales;
SQL

Result:

productsales_amountproduct_totalproduct_avgproduct_maxproduct_minproduct_count
A100400133.332001003
A200400133.332001003
A100400133.332001003
B200800266.674002003
B200800266.674002003
B400800266.674002003
C1505002503501502
C3505002503501502

This query calculates the total, average, maximum, minimum, and count of sales_amount for each product.

In Conclusion

SQL window functions equip you with advanced data processing capabilities by enabling complex calculations across related rows. By understanding and utilizing these functions, you can increase the efficiency and versatility of your data management tasks.