There are a few ways to do this. Here's one way to do it:
create table #temp
(
Id char(1),
Amount int
);
insert into #temp values
('a', 1),
('b', 2),
('c', 3),
('d', 4),
('e', 26);
with totals as
(
select
SUM(Amount) as Total
from
#temp
)
select
Id,
cast(100.0 * Amount / Total as decimal(5,2))
from
#temp t
cross join totals tot;
drop table #temp;
I used a common table expression to get the sum, and used 100.0 to force a decimal value rather than using integer division.
Note that this only works if you want to sum everything in that set up--in other words, there shouldn't be any groups in the code. So let's suppose, going just a little further, that you do want groups. I'll split this up into groups A and B.
create table #temp2
(
Id char(1),
Classification char(1),
Amount int
);
insert into #temp2 values
('a', 'a', 1),
('b', 'a', 2),
('c', 'b', 3),
('d', 'b', 4),
('e', 'b', 26);
with totals as
(
select
Classification,
SUM(Amount) as Total
from
#temp2
group by
Classification
)
select
Id,
cast(100.0 * Amount / Total as decimal(5,2))
from
#temp2 t
inner join totals tot on t.Classification = tot.Classification;
drop table #temp2;
Instead of doing a cross join, we use an inner join, but most of the query can stay the same.
Also, if you want to have a percent sign at the end, you can use
cast(cast(100.0 * Amount / Total as decimal(5,2)) as varchar(8)) + '%'
in the query.
But honestly, in most cases, percentages should probably be done at a higher level--SQL Server Reporting Services does a good job of summing rows and formatting percentages. So if this is eventually going into SSRS or some other front-end application, I'd recommend doing it there instead.
↧