Original Problem
Using AdventureWorks2008R2, write a query to return the salesperson id, number of unique products sold, highest order value, total sales amount, and top 3 orders for each salesperson.
Use TotalDue in SalesOrderHeader when calculating the highest order value and total sales amount. The top 3 orders have the 3 highest total order quantities. If there is a tie, the tie must be retrieved. Exclude orders which don't have a salesperson for this query. Return only the salespersons whose total sales were
greater than $9800000.
Return the order value and total sales as int. Sort the returned data by SalesPersonID. The returned data should have a format as displayed below. Use the sample format for formatting purposes only.
Result
| SalesPersonID | TotalUniqueProducts | OrderValue | TotalSales | Orders |
|---|---|---|---|---|
| 275 | 242 | 165029 | 10475367 | 47395, 46666, 46662 |
| 276 | 244 | 145742 | 11695019 | 51721, 47355, 57046 |
| 277 | 246 | 132728 | 11342386 | 51748, 53560, 47027 |
Code:
WITH SalesData AS
(
SELECT
soh.SalesPersonID,
soh.SalesOrderID,
sod.ProductID,
soh.TotalDue
FROM
Sales.SalesOrderHeader soh
JOIN
Sales.SalesOrderDetail sod ON sod.SalesOrderID = soh.SalesOrderID
WHERE
soh.SalesPersonID IS NOT NULL
),
RankedSalesData AS
(
SELECT
SalesPersonID,
SalesOrderID,
TotalDue,
ROW_NUMBER() OVER (PARTITION BY SalesPersonID ORDER BY TotalDue DESC) AS SalesRank
FROM
(SELECT DISTINCT SalesPersonID, SalesOrderID, TotalDue FROM SalesData) AS UniqueSalesData
),
SalesSummary AS
(
SELECT
SalesPersonID,
COUNT(DISTINCT ProductID) AS UniqueProductsSold,
Cast(MAX(TotalDue)as int) AS HighestOrderValue,
Cast(SUM(TotalDue) as int) AS TotalSalesAmount
FROM
SalesData
GROUP BY
SalesPersonID
)
SELECT
SS.SalesPersonID,
SS.UniqueProductsSold,
SS.HighestOrderValue,
SS.TotalSalesAmount,
STUFF((SELECT ',' + CAST(R.SalesOrderID AS VARCHAR)
FROM RankedSalesData R
WHERE R.SalesPersonID = SS.SalesPersonID AND R.SalesRank <=3
FOR XML PATH('')), 1, 1, '') AS Top3Orders
FROM
SalesSummary SS
WHERE
SS.TotalSalesAmount > 9800000
ORDER BY
SS.SalesPersonID;
My result:
| Salesperson ID | Unique Product sold | HighestOrdervalue | Totalsalesamount | Top3 Orders |
|---|---|---|---|---|
| 274 | 216 | 126852 | 45434066 | 51830,57136,53465 |
| 275 | 242 | 165029 | 327853784 | 47395,53621,50289 |
| 276 | 244 | 145742 | 381125561 | 47355,51822,57186 |
| 277 | 246 | 132728 | 347868655 | 46660,43884,44528 |
| 278 | 234 | 96937 | 102841549 | 44534,43890,58932 |
| 279 | 245 | 142312 | 201612866 | 44518,43875,47455 |
If you see the TotalSales Amount, it is multiplying multiple orders into the final amount and not matching the answer. I don't know where I am doing it wrong. I already tried to debug it with ChatGPT. So, Please save your answer from that. If you can explain in detail where I go wrong, It will be greatly appreciated in my academic career. I thank you ahead.
You will have to change the object names in this. This code assumes the existence of two tables:
(These are part of a script I maintain which generates completely randomized sales data, with proper constraints and all sorts of fun)
The code should provide an example of a way to produce the results you're looking for.