Reputation: 407
Come up against an issue where I want to summarize results in a query.
Example as follows:
NAME | FRUIT | PRICE
-----+-------+------
JOHN | APPLE | 2
JOHN | APPLE | 2
JOHN | APPLE | 2
JOHN | APPLE | 2
DAVE | GRAPE | 3
DAVE | GRAPE | 3
DAVE | GRAPE | 3
This is my table at the moment, what i need though is to have a summary of Johns business, like below:
NAME | FRUIT | PRICE
-----+-------+------
JOHN | APPLE | 2
JOHN | APPLE | 2
JOHN | APPLE | 2
JOHN | APPLE | 2
JOHN | TOTAL | 8
DAVE | GRAPE | 3
DAVE | GRAPE | 3
DAVE | GRAPE | 3
DAVE | TOTAL | 9
I have tried to group the information but it does not reflect what i want, plus if John were to have different fruit it would need to sum that up before it sums up the next part and it needs to have a running total for all values in the NAME field as there will be a number of customers.
Any advice would be great
EDIT
I have tried using Rollup but I keep getting totals of all values in a seperate column where as I would like to see it as the way it is formatted above
Upvotes: 2
Views: 103
Reputation: 1269633
The solution to your problem is GROUPING SETS
. However, your rows are not unique. Alas, so this adds a unique value, just so you can keep your original rows:
with t as (
select t.*, row_number() over (order by (select null)) as seqnum
from t
)
select name, ,
coalesce(fruit, 'Total') as fruit,
sum(price) as price
from t
group by grouping sets ( (name, fruit, seqnum), (name) )
order by name,
(case when fruit is not null then 1 else 2 end);
Upvotes: 0
Reputation: 635
This will get you a running total per customer per fruit:
create table #Sales([Name] varchar(20), Fruit varchar(20), Price int)
insert into #Sales([Name], Fruit, Price)
values
('JOHN','APPLE',2),
('JOHN','APPLE',2),
('JOHN','APPLE',2),
('JOHN','APPLE',2),
('DAVE','GRAPE',3),
('DAVE','GRAPE',3),
('DAVE','GRAPE',3)
Select c.*
, SUM(Price) OVER (PARTITION BY c.[Name], c.[Fruit] ORDER BY c.[Name], c.[Fruit] rows between unbounded preceding and current ROW ) as RunningTotal
from #Sales c
order by c.[Name], c.[Fruit] asc
drop table #Sales
Output:
Upvotes: 1
Reputation: 14189
A solution with UNION
and GROUP BY
.
;WITH PricesWithTotals AS
(
SELECT
Name,
Fruit,
Price
FROM
YourTable
UNION ALL
SELECT
Name,
Fruit = 'TOTAL',
Price = SUM(Price)
FROM
YourTable
GROUP BY
Name
)
SELECT
Name,
Fruit,
Price
FROM
PricesWithTotals
ORDER BY
Name,
CASE WHEN Fruit <> 'Total' THEN 1 ELSE 999 END ASC,
Fruit
Upvotes: 3