Reputation: 7961
#travel expense = select sum(val) from expenses where type = 'travel';
#food expense = select sum(val) from expenses where type = 'food';
#phone expense = select sum(val) from expenses where type = 'phone';
#total expense = select sum(val) from expenses;
How do I find a % of each expense in one query? Say $1000 total expenses and 50% of it is for food, 30% for travel and the rest for phone?
travel expense = (select sum(val) from expenses where type = 'travel')/(select sum(val) from expenses)*100 ==> What is the equivalent of this query in one query rather than two?
Upvotes: 0
Views: 63
Reputation: 43434
Try this:
select type, sum(val) / (select sum(val) from expenses) * 100 Percentage
from expenses
group by type
Result:
+--------+------------+
| TYPE | PERCENTAGE |
+--------+------------+
| food | 17.7778 |
| other | 20 |
| phone | 35.5556 |
| travel | 26.6667 |
+--------+------------+
This assumes you want a percentage for all expenses in the table. If you have some other expenses you want to filter out then run this:
select type, sum(val) /
(select sum(val) from expenses
where type in ('travel', 'phone', 'food')) * 100 Percentage
from expenses
where type in ('travel', 'phone', 'food')
group by type
+--------+------------+
| TYPE | PERCENTAGE |
+--------+------------+
| food | 22.2222 |
| phone | 44.4444 |
| travel | 33.3333 |
+--------+------------+
Upvotes: 1
Reputation: 48139
select
PreAggregate.TotalExpenses,
PreAggregate.TotalTravel,
PreAggregate.TotalTravel / PreAggregate.TotalExpenses as PctForTravel,
PreAggregate.TotalFood,
PreAggregate.TotalFood / PreAggregate.TotalExpenses as PctForFood,
PreAggregate.TotalPhone,
PreAggregate.TotalPhone / PreAggregate.TotalExpenses as PctForPhone,
PreAggregate.TotalExpenses,
PreAggregate.ExpenseItems
from
( select
sum( if( type = 'travel', val, 0 )) as TotalTravel,
sum( if( type = 'food', val, 0 )) as TotalFood,
sum( if( type = 'phone', val, 0 )) as TotalPhone,
sum( val ) as TotalExpenses,
count(*) as ExpenseItems
from
expenses
where
type in ( 'travel', 'food', 'phone' ) ) PreAggregate
Upvotes: 0
Reputation: 14149
Can you do:
SELECT type, COUNT(*) FROM expenses GROUP BY type WITH ROLLUP;
...and pull it together yourself from there? It does provide all the data you need in a single query even if you have to do a little work outside the query.
Upvotes: 0
Reputation: 360572
Can't really do it in a "single" query, since you need both per-row and aggregate data to do this, but with some subqueries, it'll work:
SELECT ((
SELECT SUM(val) FROM expenses WHERE type='travel'
) / (
SELECT SUM(val) FROM expenses
)) AS pct
Upvotes: 1