Суммировать строки не в верхних x строках группы в таблице в «другую» строку? - PullRequest
0 голосов
/ 29 апреля 2020

Если у меня есть таблица, подобная следующей, которая представляет собой количество записей с данным ярлыком, сгруппированных по определенной категории (в данном случае Мужской, Женский),

Number           Label     Category
51               A         M     
43               B         M   
22               C         M 
9                D         M  
6                E         M   
3                X         M
2                Y         M
2                Z         M
40               A         F
37               B         F
34               C         F
17               D         F
12               E         F
6                X         F
3                Y         F
1                Z         F

Как бы я преобразовал ее в таблица, которая хранит верхний x (например, 5 записей) для каждой категории, когда строки отсортированы по убыванию числа, и суммирует оставшиеся строки для этой категории в «другую» строку? Желаемый результат (при условии, что мы держим топ-5) ниже:

Number           Label     Category
51               A         M     
43               B         M   
22               C         M 
9                D         M  
6                E         M   
7                Other     M
40               A         F
37               B         F
34               C         F
17               D         F
12               E         F
10               Other     F

Ответы [ 2 ]

2 голосов
/ 29 апреля 2020

Вы можете использовать оконные функции и агрегирование:

select sum(t.number) as number, v.label, t.category
from (select t.*, row_number() over (partition by category order by number desc) as seqnum
      from t
     ) t cross appy
     (values (case when seqnum <= 5 then label else 'Other' end)
     ) v(label)
group by v.label, t.category;
1 голос
/ 29 апреля 2020

Вы можете использовать row_number() и агрегацию:

select sum(number) number, new_label label, category
from (
    select
        t.*,
        case 
            when row_number() over(partition by category order by number) <= 5
            then label
            else 'Other'
        end new_label
    from mytable
) t
group by new_label, category
order by category, number desc
...