Как суммировать значения после первых трех строк и группировать их под другими - PullRequest
6 голосов
/ 24 июня 2019

У меня есть следующая таблица участников завершения сбора яблок. У меня есть таблица, где все участники видны с количеством яблок, которые они выбрали.

Теперь я хочу таблицу, в которой будут отображаться только первые 3, а остальные будут сгруппированы в разделе «Другие», а общее количество выбранных яблок должно отображаться на фоне других

Я создал таблицу, в которой будут собраны все идентификаторы и общее количество собранных яблок

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

Я не уверен, как добавить все после 3-го и подвести итог. Любое руководство очень ценится

Ответы [ 4 ]

2 голосов
/ 24 июня 2019
;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 голос
/ 24 июня 2019

Просто еще один вариант с использованием 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
1 голос
/ 24 июня 2019

Требуется функция окна:

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

Вот Демо .

0 голосов
/ 24 июня 2019

Я бы сделал это с двумя таблицами #Temp.Выберите топ 3 в первый;выберите сумму всех строк, чьи идентификаторы находятся не в первой, а во второй;вернуть объединение двух таблиц #Temp.

Вы можете использовать таблицы CTE вместо таблиц #Temp - логика будет такой же.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...