取材自真實商業問題的 5 道 SQL 視窗函數練習
5 SQL Window-Function Exercises Taken From Real Business Problems
文章整理了 5 道取材自分析師實際工作的 SQL 視窗函數練習,涵蓋客戶累計消費、距離上一張訂單的天數、每位客戶的首張訂單、月度收入變化,以及每月消費最高的客戶(包括並列情況)。練習提供提示,並可使用 Postgres、MySQL 8 或瀏覽器實驗室作答。
Window functions are the point where most SQL learners stall. The syntax isn't hard; knowing when to reach for them is. These five exercises come from tasks analysts actually get. Try each one before reading the hint.
Use any Postgres or MySQL 8 database, or open a free browser lab at bartman.ai/labs/sql so there's nothing to install.
Setup
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE,
amount NUMERIC(10,2)
);
INSERT INTO orders VALUES
(1, 101, '2026-01-04', 1200), (2, 102, '2026-01-09', 450),
(3, 101, '2026-02-02', 800), (4, 103, '2026-02-11', 2300),
(5, 102, '2026-03-15', 300), (6, 101, '2026-03-28', 950),
(7, 104, '2026-03-30', 610), (8, 103, '2026-04-02', 1800);
1. Running revenue per customer
Task: For each order, show the customer's cumulative spend up to and including that order.
Hint
SUM(amount) OVER (PARTITION BY customer_id ORDER BY order_date)
2. Days since the previous order
Task: For each order, how many days since the same customer's previous order? First orders should show NULL.
Hint
order_date - LAG(order_date) OVER (PARTITION BY customer_id ORDER BY order_date)
3. Each customer's first order only
Task: Return one row per customer: their first order. No GROUP BY joins back to the table.
Hint
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date) in a CTE, then filter = 1.
4. Month-over-month revenue change
Task: Total revenue per month, plus the percentage change from the previous month.
Hint
Aggregate by DATE_TRUNC('month', order_date) in a CTE, then LAG(total) OVER (ORDER BY month).
5. Top customer each month, ties included
Task: For each month, the customer(s) with the highest spend. If two tie, show both.
Hint
RANK(), not ROW_NUMBER(). That one word is the whole exercise.
Where to go next
Once these feel easy, the real test is applying them to a messy business question: churn by signup cohort, multi-touch attribution, or receivables ageing. Those are full projects rather than snippets. I put a few together on Bartman, for example subscription churn with CTEs and window functions and e-commerce funnel and cohort retention, where your queries are run and checked against the expected result.
Post your solution to #5 in the comments. I'm curious how many people reach for ROW_NUMBER() first.
Written with help from AI tools.
來源:DEV Community · dev.to