<aside> 🪟 Window functions perform calculations across a set of rows related to the current row — without collapsing rows like GROUP BY does.
</aside>
function_name() OVER (
PARTITION BY column -- divide rows into groups (optional)
ORDER BY column -- sort within partition (optional)
ROWS BETWEEN ... -- define the window frame (optional)
)
SELECT
OrderID, OrderDate, Sales,
SUM(Sales) OVER () AS TotalSales -- sum of ALL rows
FROM Sales.Orders;
SELECT
OrderID, ProductID, Sales,
SUM(Sales) OVER () AS TotalSales,
SUM(Sales) OVER (PARTITION BY ProductID) AS SalesByProduct
FROM Sales.Orders;
-- Cumulative (running) total of sales by product
SELECT
OrderID, ProductID, OrderDate, Sales,
SUM(Sales) OVER (
PARTITION BY ProductID
ORDER BY OrderDate
) AS RunningTotal
FROM Sales.Orders;
-- Current row and 2 following rows
SUM(Sales) OVER (
PARTITION BY OrderStatus
ORDER BY OrderDate
ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING
)
-- Previous 2 rows and current row
SUM(Sales) OVER (
PARTITION BY OrderStatus
ORDER BY OrderDate
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
)
-- From start to current row (cumulative)
SUM(Sales) OVER (
PARTITION BY OrderStatus
ORDER BY OrderDate
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
)
SELECT
OrderID, ProductID, Sales,
ROW_NUMBER() OVER (ORDER BY Sales DESC) AS RowNum, -- unique always
RANK() OVER (ORDER BY Sales DESC) AS Rank, -- gaps on ties
DENSE_RANK() OVER (ORDER BY Sales DESC) AS DenseRank, -- no gaps on ties
NTILE(4) OVER (ORDER BY Sales DESC) AS Quartile, -- divide into buckets
CUME_DIST() OVER (ORDER BY Sales DESC) AS CumeDist -- cumulative distribution
FROM Sales.Orders;