SQL Analysis — Sales Dashboard¶
Setup
Load superstore_clean.csv into a table called sales. Key columns: order_id, order_date, segment, region, category, sub_category, product_name, customer_id, customer_name, sales, quantity, discount, profit.
Q1 — Overall Revenue and Profit¶
SELECT
COUNT(DISTINCT order_id) AS total_orders,
COUNT(DISTINCT customer_id) AS total_customers,
ROUND(SUM(sales), 0) AS total_revenue,
ROUND(SUM(profit), 0) AS total_profit,
ROUND(SUM(profit) / SUM(sales) * 100, 1) AS margin_pct,
ROUND(SUM(sales) / COUNT(DISTINCT order_id), 2) AS avg_order_value
FROM sales;
Sample output:
| total_orders | total_customers | total_revenue | total_profit | margin_pct | avg_order_value |
|---|---|---|---|---|---|
| 5009 | 793 | 2297201 | 286397 | 12.5 | 458.61 |
Q2 — Monthly Revenue Trend with Growth¶
WITH monthly AS (
SELECT
order_month,
SUM(sales) AS revenue,
SUM(profit) AS profit
FROM sales
GROUP BY order_month
)
SELECT
order_month,
ROUND(revenue, 0) AS revenue,
ROUND(profit, 0) AS profit,
ROUND(LAG(revenue) OVER (ORDER BY order_month), 0) AS prev_month,
ROUND(
(revenue - LAG(revenue) OVER (ORDER BY order_month))
/ LAG(revenue) OVER (ORDER BY order_month) * 100, 1
) AS mom_growth_pct
FROM monthly
ORDER BY order_month;
Q3 — Revenue and Profit by Category¶
SELECT
category,
ROUND(SUM(sales), 0) AS revenue,
ROUND(SUM(profit), 0) AS profit,
ROUND(SUM(profit) / SUM(sales) * 100, 1) AS margin_pct,
ROUND(SUM(sales) / SUM(SUM(sales)) OVER () * 100, 1) AS revenue_share_pct
FROM sales
GROUP BY category
ORDER BY revenue DESC;
Sample output:
| category | revenue | profit | margin_pct | revenue_share_pct |
|---|---|---|---|---|
| Technology | 836154 | 145455 | 17.4 | 36.4 |
| Furniture | 742000 | 18451 | 2.5 | 32.3 |
| Office Supplies | 719047 | 122491 | 17.0 | 31.3 |
The Furniture problem
Furniture is the #2 revenue category but generates only 6% of total profit. Its 2.5% margin is 7× lower than the other categories. This needs investigation in the dashboard.
Q4 — Worst Sub-Categories by Profit¶
SELECT
sub_category,
category,
ROUND(SUM(sales), 0) AS revenue,
ROUND(SUM(profit), 0) AS profit,
ROUND(SUM(profit) / SUM(sales) * 100, 1) AS margin_pct,
ROUND(AVG(discount) * 100, 1) AS avg_discount_pct
FROM sales
GROUP BY sub_category, category
ORDER BY profit ASC
LIMIT 5;
Sample output:
| sub_category | category | revenue | profit | margin_pct | avg_discount_pct |
|---|---|---|---|---|---|
| Tables | Furniture | 206966 | -17725 | -8.6 | 26.1 |
| Bookcases | Furniture | 114880 | -3473 | -3.0 | 21.1 |
| Supplies | Office Supplies | 46674 | -1189 | -2.5 | 7.6 |
Tables LOSE money — they generate $207k in revenue but a $17.7k loss, driven by a 26% average discount.
Q5 — Discount vs Profit Relationship¶
SELECT
discount_band,
COUNT(*) AS line_items,
ROUND(SUM(sales), 0) AS revenue,
ROUND(SUM(profit), 0) AS profit,
ROUND(AVG(profit_margin) * 100, 1) AS avg_margin_pct
FROM sales
GROUP BY discount_band
ORDER BY discount_band;
Sample output:
| discount_band | line_items | revenue | profit | avg_margin_pct |
|---|---|---|---|---|
| No Discount | 4798 | 1087908 | 320987 | 29.5 |
| Low (0-20%) | 3156 | 701872 | 95430 | 13.6 |
| Medium (20-40%) | 1241 | 287654 | -28765 | -10.0 |
| High (40%+) | 799 | 219767 | -101255 | -46.1 |
The killer insight
Profit turns negative at discounts above 20%. Orders discounted 40%+ generate a -46% margin — the company pays customers to take the product. Capping discounts at 20% would dramatically improve profitability.
Q6 — Top 10 Customers by Revenue¶
SELECT
customer_name,
segment,
COUNT(DISTINCT order_id) AS orders,
ROUND(SUM(sales), 0) AS revenue,
ROUND(SUM(profit), 0) AS profit
FROM sales
GROUP BY customer_name, segment
ORDER BY revenue DESC
LIMIT 10;
Q7 — Regional Performance¶
SELECT
region,
COUNT(DISTINCT order_id) AS orders,
ROUND(SUM(sales), 0) AS revenue,
ROUND(SUM(profit), 0) AS profit,
ROUND(SUM(profit) / SUM(sales) * 100, 1) AS margin_pct
FROM sales
GROUP BY region
ORDER BY revenue DESC;
Sample output:
| region | orders | revenue | profit | margin_pct |
|---|---|---|---|---|
| West | 1611 | 725458 | 108418 | 14.9 |
| East | 1401 | 678781 | 91523 | 13.5 |
| Central | 1175 | 501240 | 39706 | 7.9 |
| South | 822 | 391722 | 46749 | 11.9 |
Central region has the lowest margin (7.9%) despite respectable revenue — worth investigating its discount practices.
Q8 — Segment Performance¶
SELECT
segment,
COUNT(DISTINCT customer_id) AS customers,
COUNT(DISTINCT order_id) AS orders,
ROUND(SUM(sales), 0) AS revenue,
ROUND(SUM(sales) / COUNT(DISTINCT customer_id), 0) AS revenue_per_customer
FROM sales
GROUP BY segment
ORDER BY revenue DESC;
Q9 — Top Products per Category (Window Function)¶
WITH product_revenue AS (
SELECT
category,
product_name,
SUM(sales) AS revenue,
SUM(profit) AS profit,
ROW_NUMBER() OVER (PARTITION BY category ORDER BY SUM(sales) DESC) AS rn
FROM sales
GROUP BY category, product_name
)
SELECT category, product_name, ROUND(revenue, 0) AS revenue, ROUND(profit, 0) AS profit
FROM product_revenue
WHERE rn <= 3
ORDER BY category, revenue DESC;