jdylanmc
jdylanmc

Reputation: 859

Return value's percentage of sub category in SQL

I have a query: (using a very simple example)

SELECT
    ItemCategory,
    ItemID,
    Sales
FROM
    MyTable
WHERE
    CustomerID = 1

Which returns

ItemCategory | ItemID | Sales
A              0        75.00    
A              1        50.00
A              2         0.00
B              3        25.00
B              4        25.00
C              5        20.00 
C              6        30.00
C              7        10.00
C              8         0.00
C              9        50.00

How can I modify this query so that I receive the percentage of sales for each item grouped by ItemCategory?

That is, I would like this returned:

ItemCategory | ItemID | Sales  | PercentageOfCategory
A              0        75.00    60%
A              1        50.00    40%
A              2         0.00     0%
B              3        25.00    50%
B              4        25.00    50%
C              5        20.00    20%
C              6        30.00    30%
C              7        10.00    10%
C              8         0.00     0%
C              9        50.00    50%

I tried to keep the example as trivial as possible, the actual query is pretty complex but I imagine the same logic still applies.

EDIT: I believe the server is sql server 2008

Upvotes: 2

Views: 3145

Answers (3)

Martin Smith
Martin Smith

Reputation: 453327

You can use SUM ... OVER

SELECT
    ItemCategory,
    ItemID,
    Sales,
    100.0 * Sales / 
    NULLIF(SUM(Sales) OVER (PARTITION BY ItemCategory),0) AS PercentageOfCategory
FROM
    MyTable
WHERE
    CustomerID = 1

Upvotes: 0

Joe Stefanelli
Joe Stefanelli

Reputation: 135818

Assuming SQL Server 2005+ for the CTE:

WITH cteCategoryTotals AS (
    SELECT ItemCategory, SUM(Sales) AS TotalSales
        FROM MyTable
        WHERE CustomerID = 1
        GROUP BY ItemCategory)
SELECT m.ItemCategory, m.ItemId, m.Sales, (m.Sales/c.TotalSales)*100.0 AS PercentageOfCategory
    FROM MyTable m
        INNER JOIN cteCategoryTotals
            ON m.ItemCategory= c.ItemCategory
    WHERE m.CustomerID = 1

Upvotes: 1

amit_g
amit_g

Reputation: 31250

You did not mention what version of SQL server but if you have 2005+ then you could use Common Table Expressions (CTE)

;WITH RawData As
(
    SELECT
        ItemCategory,
        ItemID,
        Sales
    FROM
        MyTable
    WHERE
        CustomerID = 1
),
GroupedData As
(
    SELECT
        ItemCategory,
        Sum(Sales) As TotalSales
    FROM
        RawData
    GROUP BY
        ItemCategory
)
SELECT
    R.ItemCategory,
    R.ItemID,
    R.Sales,
    R.Sales / G.TotalSales * 100.0 As PercentageSales
FROM
    RawData R
INNER JOIN
    GroupedData G
ON
    R.ItemCategory = G.ItemCategory

Upvotes: 2

Related Questions