Metal model for SQL queries

These are some ways of thinking about applying the fucntion to make the SQL query for a problem.
1. Looking Across Rows
LAG()→ look backLEAD()→ look forward
2. Accumulating
SUM() OVER()→ running totalAVG() OVER()→ running average
3. Ranking
ROW_NUMBER()→ unique orderRANK()→ gapsDENSE_RANK()→ no gaps
4. Bucketing
NTILE(4)→ quartiles
5. Distribution
PERCENT_RANK()CUME_DIST()

Lets think we are given a sales transactions dataset.
sales (
order_id INT,
customer_id INT,
order_date DATE,
amount DECIMAL
)
Can you show me running totals?
SELECT
order_date,
amount,
SUM(amount) OVER (ORDER BY order_date) AS running_total
FROM sales;
“Compare each order with the previous one.”
“Compare each order with the previous one.”
SELECT
order_id,
amount,
LAG(amount) OVER (ORDER BY order_date) AS prev_amount,
amount - LAG(amount) OVER (ORDER BY order_date) AS diff
FROM sales;
“I want top 3 customers per region.”
SELECT *
FROM (
SELECT
customer_id,
region,
SUM(amount) AS total_spent,
ROW_NUMBER() OVER (PARTITION BY region ORDER BY SUM(amount) DESC) AS rn
FROM sales
GROUP BY customer_id, region
) t
WHERE rn <= 3;
“Your dataset has missing days”
SELECT
order_date,
LAG(order_date) OVER (ORDER BY order_date) AS prev_date,
order_date - LAG(order_date) OVER (ORDER BY order_date) AS gap
FROM sales;
“Smooth the noise. Show me a 3-day moving average.”
SELECT
order_date,
amount,
AVG(amount) OVER (
ORDER BY order_date
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) AS moving_avg
FROM sales;
“Remove duplicates, keep latest”
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY order_id
ORDER BY order_date DESC
) AS rn
FROM sales
) t
WHERE rn = 1;
“Who improved month over month?”
SELECT
customer_id,
order_date,
amount,
LAG(amount) OVER (
PARTITION BY customer_id
ORDER BY order_date
) AS prev_amount,
amount - LAG(amount) OVER (
PARTITION BY customer_id
ORDER BY order_date
) AS growth
FROM sales;