Customer Purchase Frequency Analysis
For each customer who has placed at least one order, show their total orders, total spent, average order value, and rank them by total spend.
- Window functions
- Joins
- Aggregation
- Numeric functions
- Sorting
Challenge brief
Understand the request
Customer Success is identifying high-value customers for the AppleCare priority programme and needs a ranked spend analysis.
Calculate customer purchase metrics and rank by total spend using RANK() window function.
Return
- customer_name (full name)
- total_orders
- total_spent (rounded 2)
- avg_order_value (rounded 2)
- customer_rank (RANK by total_spent desc)
Constraints
- Return customers with at least one order
- Customers with equal spend share a rank
- Show total spend descending and resolve display ties by customer ID
Data you will use
Review the relevant tables before deciding how to join, filter, or aggregate them.
customers
customer_idINTEGERfirst_nameVARCHAR(50)last_nameVARCHAR(50)
orders
order_idINTEGERcustomer_idINTEGERtotal_amountREALstatusVARCHAR(50)
Hints, when you need them
Open one clue at a time so you still do the reasoning.
Hint 1
Customer names are in customers. Order amounts are in orders. JOIN on customer_id, GROUP BY customer, aggregate spend metrics. RANK() ranks by total spend.
Hint 2
INNER JOIN customers to orders on customer_id. GROUP BY customer_id. SUM(total_amount), COUNT(order_id), AVG(total_amount). RANK() OVER (ORDER BY SUM(total_amount) DESC).
Hint 3
Build question 8 from its business grain: identify the driving rows, add only valid relationships, then apply the required filtering, aggregation, and deterministic ordering.
Verified SQL answer
Attempt the problem first, then compare structure and reasoning—not just syntax.
Reveal solution and explanation
SELECT c.first_name || ' ' || c.last_name AS customer_name, COUNT(o.order_id) AS total_orders, ROUND(SUM(o.total_amount), 2) AS total_spent, ROUND(AVG(o.total_amount), 2) AS avg_order_value, RANK() OVER (ORDER BY SUM(o.total_amount) DESC) AS customer_rank FROM customers c INNER JOIN orders o ON c.customer_id = o.customer_id GROUP BY c.customer_id, c.first_name, c.last_name ORDER BY total_spent DESC, c.customer_id ASC;Why this works
RANK() runs after GROUP BY so it ranks the aggregated totals. All 6 customers have orders so all appear. Carol White edges out Alice Johnson ($3,798 vs $3,747) despite having fewer orders — she bought more expensive items.
Success check
6 customers — Carol White leads at $3,798, David Brown is last at $399
Expected result
Use this output to verify values, aliases, ordering, and row count.
| customer_name | total_orders | total_spent | avg_order_value | customer_rank |
|---|---|---|---|---|
| Carol White | 2 | 3798 | 1899 | 1 |
| Alice Johnson | 3 | 3747 | 1249 | 2 |
| Bob Smith | 2 | 2398 | 1199 | 3 |
| Frank Miller | 1 | 1048 | 1048 | 4 |
| Emma Davis | 1 | 799 | 799 | 5 |
| David Brown | 1 | 399 | 399 | 6 |
Learn the concepts behind this answer
Strengthen your understanding with these targeted learning topics:
Continue practicing
Explore related company challenges
Microsoft
Independent Microsoft-style cloud, productivity, subscription, usage, support, and customer analytics SQL practice.
Google
Independent Google-style search, advertising, user-engagement, and video-product SQL practice.
Amazon
Independent Amazon-style e-commerce, warehouse, inventory, and customer analytics SQL practice.
Return to the complete interview preparation experience.