Unable to get Targeted total sales amount

64 views Asked by At

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.

1

There are 1 answers

0
Patrick Hurst On BEST ANSWER

You will have to change the object names in this. This code assumes the existence of two tables:

CREATE TABLE InvoiceItems (InvoiceItemID BIGINT IDENTITY(1,1) NOT NULL, InvoiceID BIGINT NOT NULL, Sequence INT NULL, Quantity INT NULL, Cost DECIMAL(7, 2) NULL, Price DECIMAL(7, 2) NULL, ProductID BIGINT NULL)
CREATE TABLE Invoices (InvoiceID BIGINT IDENTITY(1,1) NOT NULL, InvoiceDateTimeUTC DATETIME2(7) NULL, CustomerID BIGINT NULL, EmployeeID BIGINT NULL, StoreID INT NULL)

(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.

USE RandomSales;

;WITH Sales AS (
SELECT i.InvoiceID, i.InvoiceDateTimeUTC, i.CustomerID, i.EmployeeID, i.StoreID, ii.InvoiceItemID, ii.Sequence, ii.Quantity, ii.Cost, ii.Price, ii.ProductID, 
       ii.Price*ii.Quantity AS ItemTotal, 
       ii.Cost*ii.Quantity AS ItemValue, 
       SUM(ii.Price*ii.Quantity) OVER (PARTITION BY i.InvoiceID ORDER BY @@SPID) AS InvoiceTotal,
       SUM(ii.Cost*ii.Quantity) OVER (PARTITION BY i.InvoiceID ORDER BY @@SPID) AS InvoiceValue,
       SUM(ii.Quantity) OVER (PARTITION BY i.InvoiceID ORDER BY @@SPID) AS QuantityTotal
  FROM dbo.Invoices i
    INNER JOIN dbo.InvoiceItems ii
      ON ii.InvoiceID = i.InvoiceID
), QtyRankByEmployee AS (
SELECT EmployeeID, STRING_AGG(InvoiceId,', ') AS Invoices
  FROM (
        SELECT Sales.EmployeeID, Sales.InvoiceID, MAX(Sales.QuantityTotal) AS Qty, RANK() OVER (PARTITION BY Sales.EmployeeID ORDER BY MAX(Sales.QuantityTotal) DESC) AS QtyRank
          FROM Sales
         GROUP BY Sales.EmployeeID, Sales.InvoiceID
       ) a
 WHERE a.QtyRank <= 3
 GROUP BY a.EmployeeID
), EmployeeTotal AS (
SELECT EmployeeID, COUNT(DISTINCT ProductID) AS TotalUniqueProducts, SUM(InvoiceValue) AS TotalValue, SUM(InvoiceTotal) AS TotalSales
  FROM Sales s
 GROUP BY EmployeeID
)

SELECT e.EmployeeID, e.TotalUniqueProducts, e.TotalValue, e.TotalSales, q.Invoices
  FROM EmployeeTotal e
    LEFT OUTER JOIN QtyRankByEmployee q
      ON e.EmployeeID = q.EmployeeID
EmployeeID TotalUniqueProducts TotalValue TotalSales Invoices
1 31 6527.00 9082.20 8, 17, 5, 9
2 31 14397.00 19951.10 29, 37, 50
3 31 17304.00 24658.40 80, 86, 90
4 31 9992.50 14061.20 147, 152, 137
5 30 9608.00 13637.30 176, 201, 168
6 31 13396.00 18578.20 261, 257, 219
7 31 13850.50 19199.30 303, 306, 279, 285, 287
8 31 12420.00 17395.10 323, 327, 353, 368
9 31 16013.00 22568.50 409, 383, 382, 394, 370
10 31 12976.50 18055.10 423, 432, 434, 435
11 31 11641.00 16178.70 505, 496, 497, 486
12 31 10915.50 15387.40 529, 542, 544
13 31 14112.00 19650.70 556, 591, 587
14 31 15196.00 21490.90 617, 643, 644, 619, 628, 611
15 31 16220.50 22603.80 667, 652, 656, 686, 688
16 31 13231.50 18714.90 731, 727, 738, 742, 751, 711
17 31 11027.50 15881.30 754, 785, 788
... ... ... ... ...