【问题标题】:sql: sum of highest n values in each group [duplicate]sql:每组中最高n值的总和[重复]
【发布时间】:2019-07-03 21:00:07
【问题描述】:

我需要找到每组中 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  

使用连接和组的sql

谢谢

【问题讨论】:

  • 您使用的是什么版本的 SQL?你试过了吗?
  • 在考虑发布问题之前,请阅读How to Ask 和重新研究的投票箭头鼠标悬停文本。在这里,您可以使用“site:stackoverflow.com”搜索您的标题。

标签: sql join group-by sum window-functions


【解决方案1】:

示例数据集:

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

【讨论】:

    【解决方案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     |
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-24
      • 1970-01-01
      • 1970-01-01
      • 2018-01-09
      • 2021-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多