sql:每个组中最高n值的总和

时间:2019-02-10 01:01:36

标签: sql join sum

我需要找到每个组中n个最大值的总和。

使用(n = 2):

group | points  
g1    |  3  
g2    |  3  
g3    |  4  
g1    |  2  
g1    |  4  
g2    |  5  
g2    |  5  
g3    |  1  
g3    |  2  

结果

group | sum  
g1    | 7  
g2    | 10  
g3    | 6  

使用联接和组的

谢谢

2 个答案:

答案 0 :(得分:2)

如果RDBMS支持窗口功能,则可以使用ROW_NUMBER()为组中的每个记录分配一个数字(按点排序),然后在外部汇总查询中过滤出每个组的前2条记录。

SELECT grp, SUM(points) total
FROM (
    SELECT grp, points, ROW_NUMBER() OVER(PARTITION BY grp ORDER BY points DESC) rn
    FROM mytable
) x 
WHERE rn <= 2
GROUP BY grp
ORDER BY grp

MySQL 8.0 DB Fiddle 和您的示例数据可得出:

| grp | total |
| --- | ----- |
| g1  | 7     |
| g2  | 10    |
| g3  | 6     |

答案 1 :(得分:0)

示例数据集:

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)

处理此问题的另一种方法是使用“交叉应用”,例如下面的Sql Server:

--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

由于这里的@n值不是静态的,并且将根据用户的选择进行更改,因此可以使用如下所示的动态查询:

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