我该如何对前3行后的值求和并将其分组

时间:2019-06-24 14:00:54

标签: sql sql-server

我有下表的苹果采摘完成参与者。我有一张桌子,所有参与者都可以看到他们选出的苹果数量。

现在我想要一张只显示前三名的表,其余的将被分组在“其他”下,并且摘下的苹果总数应该与其他

我已经创建了一个表,其中将包含所有ID和已收集的所有苹果

declare  @t table
    (
        id int,
        Apples_picked int
    )

    insert into @t
    select 1,10
    union
    select 2,12
    union
    select 3,3
    union
    select 4,15
    union
    select 5,23

上表的必需输出

ID  Name    Apples picked
5   winner  23
4   2nd     15
2   3rd     12
    Others  13

我不确定如何将3rd之后的所有内容相加并总结任何指导意见

4 个答案:

答案 0 :(得分:2)

;WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (ORDER BY Apples_picked DESC) rn
    FROM @t
)
SELECT ID, 
    CASE rn WHEN 1 THEN 'Winner' WHEN 2 THEN '2nd' WHEN 3 THEN '3rd' END AS Name, 
    cte.Apples_picked
FROM cte 
WHERE rn <= 3
UNION ALL 
SELECT NULL, 'Others', SUM(apples_picked)
FROM cte
WHERE rn > 3

返回:

ID      Name    Apples_picked
5       Winner  23
4       2nd     15
2       3rd     12
NULL    Others  13

答案 1 :(得分:1)

您想要窗口功能:

select max(case when Name <> 'Others' then id end) id,  Name, sum(Apples_picked) as [Apples picked]
from (select t.*, 
             dense_rank() over (order by Apples_picked desc) as seq
      from @t t
     ) t cross apply
     ( values (case seq when 1 then 'winner' when 2 then '2nd' when 3 then '3rd' else 'Others' end) 
     ) tt(Name)
where seq <= 33
group by Name
order by id desc;

如果order by确实很重要,则可以更改:

ORDER BY (CASE WHEN Name = 'Others' THEN 1 ELSE 0 END), [Apples picked] DESC

这里是Demo

答案 2 :(得分:1)

另一个使用 CHOOSE()

的选项

示例

;WITH cte AS (
    Select *
          ,[Name] = IsNull(choose(ROW_NUMBER() OVER (ORDER BY Apples_picked DESC),'Winner','2nd','3rd'),'Others')
    FROM @t
)
Select ID = max(case when [Name]='Others' then null else ID end)
      ,[Name]
      ,Apples_picked=sum(Apples_picked)
 From cte
 Group By Name
 Order By case when [Name]='Others' then 1 else 0 end
         ,sum(Apples_picked) Desc

返回

ID      Name    Apples_picked
5       Winner  23
4       2nd     15
2       3rd     12
NULL    Others  13

答案 3 :(得分:0)

我会用两个#Temp表来做到这一点。选择前三名;选择ID不在第一行到第二行的所有行的总和;返回两个#Temp表的并集。

您可以使用CTE而不是#Temp表-逻辑将是相同的。