Example dataset:
create table #temp (name varchar(20), value int)
insert into #temp values ('g1',2),('g2',2),('g3',2),('g2',7),
('g3',9),('g1',4),('g2',8),('g3',1),('g1',3),('g1',11)
Another way to handle this issue is to use "cross apply" like in Sql Server below:
--This returns top 2 rows for each group where its value is highest.
SELECT x.*
FROM ( SELECT DISTINCT name FROM #temp ) c
CROSS APPLY ( SELECT TOP 2 * FROM #temp t WHERE c.name = t.name order by value desc ) x
--This returns sum of top 2 value of each group
SELECT x.name, SUM(x.Value) as Total
FROM ( SELECT DISTINCT name FROM #temp ) c
CROSS APPLY ( SELECT TOP 2 * FROM #temp t WHERE c.name = t.name order by value desc ) x
group by x.name
Since your @n value here is not static, and will be changed based on user's choice, you can use dynamic query like below:
declare @n int = 2;
declare @sql nvarchar(max) = 'SELECT x.name, SUM(x.Value) as Total
FROM ( SELECT DISTINCT name FROM #temp ) c
CROSS APPLY ( SELECT TOP '+cast(@n as nvarchar(10))+' * FROM #temp t
WHERE c.name = t.name order by value desc ) x
group by x.name'
exec sp_executesql @sql