Skip to main content

Window Functions

Window functions compute values across related rows while still returning each row.

Unlike GROUP BY, they do not collapse rows.

Core Concepts

flowchart LR
A[Input rows] --> B[Define window: PARTITION / ORDER]
B --> C[Compute per-row analytic value]
C --> D[Rows preserved with extra columns]
Window componentPurpose
PARTITION BYGroup rows for separate calculations
ORDER BY (in window)Define row sequence inside partition
Window functionROW_NUMBER, SUM(...) OVER, etc.
SELECT
category,
name,
price,
ROW_NUMBER() OVER (
PARTITION BY category
ORDER BY price DESC
) AS rn
FROM products_win
ORDER BY category, rn;
categorynamepricern
hardwarePro Keyboard150.01
hardwareKeyboard100.02
hardwareMouse50.03
stationeryPen Set40.01
stationeryNotebook20.02

Code Examples

-- Setup data for window examples.
CREATE TABLE products_win (
product_id INTEGER PRIMARY KEY,
category TEXT NOT NULL,
name TEXT NOT NULL,
price REAL NOT NULL
);

INSERT INTO products_win (category, name, price)
VALUES
('hardware', 'Mouse', 50.0),
('hardware', 'Keyboard', 100.0),
('hardware', 'Pro Keyboard', 150.0),
('stationery', 'Notebook', 20.0),
('stationery', 'Pen Set', 40.0);
Expected output
Table created and five rows inserted.
-- Compare each product price to category average.
SELECT
category,
name,
price,
AVG(price) OVER (PARTITION BY category) AS category_avg
FROM products_win
ORDER BY category, price DESC;
categorynamepricecategory_avg
hardwarePro Keyboard150.0100.0
hardwareKeyboard100.0100.0
hardwareMouse50.0100.0
stationeryPen Set40.030.0
stationeryNotebook20.030.0

SQLite-Specific Nuances

SQLite Nuance

Window functions are available in SQLite 3.25.0 and newer.

Verify your version if queries fail with window-function syntax errors.

Common Pitfalls / Best Practices

Pitfall

Confusing ORDER BY inside OVER(...) with final result ordering.

They serve different purposes.

Best Practice

Use window functions for per-row analytics and keep an explicit final ORDER BY for output presentation.

Quick Challenge

Rank products within each category by ascending price (1 = cheapest).

View Solution
SELECT
category,
name,
price,
ROW_NUMBER() OVER (
PARTITION BY category
ORDER BY price ASC
) AS price_rank
FROM products_win
ORDER BY category, price_rank;
categorynamepriceprice_rank
hardwareMouse50.01
hardwareKeyboard100.02
hardwarePro Keyboard150.03
stationeryNotebook20.01
stationeryPen Set40.02