sql server—将sql中的前n个类别与“其他”中的所有其他类别相加

xoefb8l8  于 2021-07-24  发布在  Java
关注(0)|答案(3)|浏览(353)

我正在尝试对一个数据集进行分类,其中具有前3个记录计数的描述类别将被汇总为前3个,所有其他类别将被计入“其他”类别(我这样做是为了ssrs报告的目的)。我使用了一个窗口函数来组织每个类别,但是我很难创建最终的结果。

declare @t table(id int, description varchar(50))
     insert into @t values(123, 'Cardiac'),
                 (124, 'Cardiac'),
                 (125, 'Cardiac'),
                 (126, 'Cardiac'),
                 (222, 'Digestive'),
                 (223, 'Digestive'),
                 (224, 'Digestive'),
                 (225, 'Digestive'),
                 (226, 'Digestive'),
                 (333, 'Muscular'),
                 (334, 'Muscular'),
                 (335, 'Muscular'),
                 (336, 'Muscular'),
                 (444, 'Nose'),
                 (445, 'Nose'),
                 (446, 'Nose'),
                 (447, 'Nose'),
                 (448, 'Nose'),
                 (449, 'Nose'),
                 (555, 'Ear'),
                 (555, 'Ear'),
                 (666, 'Mouth')

到目前为止我已经写了:

select *, row_number()over(partition by description order by id) as ranks
    from @t
    group by id, description

结果是:

Description   Count
       Nose          6
       Digestive     5
       Cardiac       4
       Muscular      4
       Other         3

我认为这涉及到使用一个带有count()的窗口函数,但我似乎无法理解。

jhkqcmku

jhkqcmku1#

可以使用两个聚合级别:

select (case when seqnum <= 4 then description else 'Other' end), sum(cnt) as cnt
from (select description, count(*) as cnt,
             row_number() over (order by count(*) desc) as seqnum
      from @t
      group by description
     ) d
group by (case when seqnum <= 4 then description else 'Other' end)
order by min(seqnum);
3hvapo4f

3hvapo4f2#

使用窗口功能 COUNT() :

with 
  cte as (
    select distinct
      description, 
      count(*) over (partition by description) counter
    from @t
  ),
  top3 as (select top 3 with ties * from cte order by counter desc)  
select description, counter
from (
  select description, counter, 1 ord from top3
  union all
  select distinct 'Others', count(*) over (), 2
  from @t
  where description not in (select description from top3)
) t
order by ord, counter desc

请看演示。
结果:

> description | counter
> :---------- | ------:
> Nose        |       6
> Digestive   |       5
> Cardiac     |       4
> Muscular    |       4
> Others      |       3
7kqas0il

7kqas0il3#

如果您似乎想处理关系,请使用rank()而不是row\ u number():

select description
, sum(cnt) as cnt
from (
    select case
        when rank() over(order by count(*) desc) <= 3 then description
        else 'Other' end as description
    , count(*) as cnt
    from @t
    group by description
)
group by description

相关问题