TGViewer
SQL Programming Resources SQL Programming Resources @sqlanalyst · 76.7K subscribers
Post #2582 1.99K
SQL Project Series #4

E-Commerce Sales Analysis – Advanced SQL with Window Functions 🚀

Window functions are widely used by Data Analysts to calculate rankings, running totals, moving averages, and customer insights without losing row-level details.

Business Questions

21. Rank Customers by Total Revenue

WITH customer_revenue AS (

SELECT

o.customer_id,

SUM(oi.quantity * oi.unit_price) AS revenue

FROM orders o

JOIN order_items oi ON o.order_id = oi.order_id

GROUP BY o.customer_id

)

SELECT

customer_id,

revenue,

DENSE_RANK() OVER (ORDER BY revenue DESC) AS revenue_rank

FROM customer_revenue;

22. Find the Top Selling Product in Each Category

WITH product_sales AS (

SELECT

p.category,

p.product_name,

SUM(oi.quantity) AS total_sold

FROM products p

JOIN order_items oi ON p.product_id = oi.product_id

GROUP BY p.category, p.product_name

)

SELECT *

FROM (

SELECT *,

ROW_NUMBER() OVER (

PARTITION BY category ORDER BY total_sold DESC

) AS rn

FROM product_sales

) t

WHERE rn = 1;

23. Calculate Running Revenue by Order Date

WITH daily_sales AS (

SELECT

o.order_date,

SUM(oi.quantity * oi.unit_price) AS daily_revenue

FROM orders o

JOIN order_items oi ON o.order_id = oi.order_id

GROUP BY o.order_date

)

SELECT

order_date,

daily_revenue,

SUM(daily_revenue) OVER (ORDER BY order_date) AS running_revenue

FROM daily_sales;

24. Find the Previous Order Date for Each Customer

SELECT

customer_id,

order_id,

order_date,

LAG(order_date) OVER (

PARTITION BY customer_id ORDER BY order_date

) AS previous_order_date

FROM orders;

25. Find the Next Order Date for Each Customer

SELECT

customer_id,

order_id,

order_date,

LEAD(order_date) OVER (

PARTITION BY customer_id ORDER BY order_date

) AS next_order_date

FROM orders;

26. Calculate Days Between Consecutive Orders

SELECT

customer_id,

order_date,

order_date - LAG(order_date) OVER (

PARTITION BY customer_id ORDER BY order_date

) AS days_between_orders

FROM orders;

Note: For Postgres use order_date - LAG(order_date) OVER(...). For MySQL use DATEDIFF(order_date, LAG(order_date) OVER(...))

27. Find the Top 3 Customers by Revenue

WITH customer_revenue AS (

SELECT

o.customer_id,

SUM(oi.quantity * oi.unit_price) AS revenue

FROM orders o

JOIN order_items oi ON o.order_id = oi.order_id

GROUP BY o.customer_id

)

SELECT *

FROM (

SELECT *,

DENSE_RANK() OVER (ORDER BY revenue DESC) AS rnk

FROM customer_revenue

) t

WHERE rnk <= 3;

28. Find Each Product's Contribution to Total Revenue

WITH product_revenue AS (

SELECT

p.product_name,

SUM(oi.quantity * oi.unit_price) AS revenue

FROM products p

JOIN order_items oi ON p.product_id = oi.product_id

GROUP BY p.product_name

)

SELECT

product_name,

revenue,

ROUND(100.0 * revenue / SUM(revenue) OVER (), 2) AS revenue_percentage

FROM product_revenue

ORDER BY revenue DESC;
  • ❤ 3
More from @sqlanalyst
  1. Oct 9, 2026SQL Interview Series — Part 5 📌 Question 5: Find Employees Who Earn More Than Their Manag…
  2. Oct 9, 2026🇮🇳 𝗚𝗢𝗩𝗘𝗥𝗡𝗠𝗘𝗡𝗧 𝗢𝗙 𝗜𝗡𝗗𝗜𝗔 — 𝗔𝗜𝗖𝗧𝗘 𝗜𝗡𝗧𝗘𝗥𝗡𝗦𝗛𝗜𝗣𝗦 𝟮𝟬𝟮𝟲 🚀…
  3. Oct 8, 2026🎓 𝗠𝗶𝗰𝗿𝗼𝘀𝗼𝗳𝘁 𝗙𝗥𝗘𝗘 𝗖𝗼𝘂𝗿𝘀𝗲𝘀 𝘄𝗶𝘁𝗵 𝗖𝗲𝗿𝘁𝗶𝗳𝗶𝗰𝗮𝘁𝗲𝘀! 🚀🔥 Upgr…
  4. Oct 7, 2026🚀𝗣𝗮𝘆 𝗔𝗳𝘁𝗲𝗿 𝗣𝗹𝗮𝗰𝗲𝗺𝗲𝗻𝘁 𝗧𝗿𝗮𝗶𝗻𝗶𝗻𝗴 | 𝗕𝗲𝗰𝗼𝗺𝗲 𝗮 𝗙𝘂𝗹𝗹𝘀𝘁𝗮𝗰…
  5. Oct 7, 2026SQL Interview Series — Part 4 📌 Question 4: Find the Highest Salary in Each Department Su…
  6. Oct 7, 2026𝗠𝗮𝘀𝘁𝗲𝗿 𝗣𝗼𝘄𝗲𝗿 𝗕𝗜 𝗳𝗼𝗿 𝗙𝗥𝗘𝗘! 🔥 Learn Power BI through these FREE learnin…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →