Reputation: 115
I have a SQL query that goes like this:
SELECT name, SUM(weight) weight, product FROM table GROUP BY name, product;
Which gives me output like this:
|name weight product |
|custA 100 trash |
|custA 300 recycling|
|custB 50 trash |
|custB 450 recycling|
Now I want to calculate the percentage of weight based on the name but still separated by product. So instead the output would look like this:
|name weight product |
|custA .25 trash |
|custA .75 recycling|
|custB .10 trash |
|custB .90 recycling|
Is there any way I can accomplish this with a regular SQL query?
Upvotes: 1
Views: 4200
Reputation: 28
Using CTE and correlated subquery
WITH TotalWeight(name, product, weightsum) AS
(
SELECT name, product, sum([weight]) as weightsum
FROM custdetails
GROUP BY name, product
)
SELECT name, product, weightsum, (0.0+weightsum)/(select sum([weight]) from custdetails where name = T.name) as percentage
FROM TotalWeight T;
This gives the following result:
name product weightsum percentage
custA recycling 300 0.750000000000
custA trash 100 0.250000000000
custB recycling 450 0.900000000000
custB trash 50 0.100000000000
Upvotes: 1
Reputation: 1270483
You can do this using window functions:
SELECT name, product, SUM(weight) as weight,
SUM(weight) / SUM(SUM(weight)) OVER (PARTITION BY name) as ratio
FROM table
GROUP BY name, product;
Note that some databases do integer division. So, if weight is an integer, you may need to convert to a decimal of some type:
SELECT name, product, SUM(weight) as weight,
SUM(weight) / SUM(1.0*SUM(weight)) OVER (PARTITION BY name) as ratio
FROM table
GROUP BY name, product;
Upvotes: 0
Reputation: 1507
Try this:
SELECT table.name, SUM(weight) / custWeightTable.custWeght as weight , product FROM table , (SELECT name, SUM (weight) as custWeight FROM table GROUP BY name) custWeightTable WHERE table.name = custWeightTable.name GROUP BY table.name, table.product;
Upvotes: 0
Reputation: 24156
try something like this:
select a.name, a.weight/b.weight, a.product
from (
select name, sum(weight) as weight, product
from table
group by name, product
) as a
inner join (
select name, sum(weight) as weight
from table
group by name
) as b
on (a.name = b.name)
Upvotes: 1