SQL 服务器:每个子组的前 5 名广告商和所有其他

SQL server: Top 5 Advertisers & All Other for each subgroup

我有一个 table 有合作伙伴 Parent --> 合作伙伴 --> 广告商,我想为每个合作伙伴拉出前 5 位广告商 "All Other" 组将其余销售额加在一起。

到目前为止我的代码:

select [Partner Parent], [Partner], [Advertiser], [Revenue]
from (
    select [Partner Parent], [Partner], [Advertiser], [Revenue] = ISNULL(SUM([Revenue]), 0),
rn = row_number() over (partition by [Partner] order by ISNULL(SUM([Revenue]), 0) DESC)
from [table]
group by [Partner Parent], [Partner], [Advertiser]
) a where a.rn <= 5

这让我获得了前 5 名...我如何在这段代码中获得 "All Other"?

我也尝试过 re-use 我在这里看到的代码,但这只是前 5 名和 "All Other" 全部,而不是合作伙伴级别

 select coalesce(d.[Advertiser], 'All Other') as [Advertiser]
   ,sum(t.[Revenue]) as [Revenue]
from   [table] t
left outer join
   (
   select top 5 [Advertiser] 
   from [table] 
   group by [Partner Parent], [Advertiser] 
   order by sum([Revenue]) desc
   ) d
          on d.[Advertiser] = t.[Advertiser]
group by  [Partner Parent], case when d.[Advertiser] is null then 1 else 0 end 
   ,coalesce(d.[Advertiser], 'All Other') 
order by case when d.[Advertiser] is null then 1 else 0 end
   ,sum(t.[Revenue]) desc

建议? 谢谢

编辑:

示例数据:

| Partner Parent |        Partner |               Advertiser | Revenue |
|----------------|----------------|--------------------------|---------|
|        Partner | Partner-Canada |               Air Canada |     500 |
|        Partner | Partner-Canada |         Mazda Motor Corp |     400 |
|        Partner | Partner-Canada |              Ford Motors |     300 |
|        Partner | Partner-Canada |        Land Rover Motors |     200 |
|        Partner | Partner-Canada |     Kaspersky Anti-Virus |     100 |
|        Partner | Partner-Canada |                   Jaguar |      10 |
|        Partner | Partner-Canada | Delta Hotels and Resorts |      10 |
|        Partner | Partner-Canada |          Toronto Tourism |      10 |
|        Partner | Partner-Canada |          Yum Restaurants |      10 |
|        Partner | Partner-Canada |        Universal Studios |      10 |
|        Partner | Partner-Norway |                 Manulife |     500 |
|        Partner | Partner-Norway |                     CIBC |     400 |
|        Partner | Partner-Norway |               Pfizer Inc |     300 |
|        Partner | Partner-Norway |            TD Bank Group |     200 |
|        Partner | Partner-Norway |         General Electric |     100 |
|        Partner | Partner-Norway |              Tim Hortons |      10 |
|        Partner | Partner-Norway |       Universal Pictures |      10 |
|        Partner | Partner-Norway |                    Dyson |      10 |
|        Partner | Partner-Norway |            Suncor Energy |      10 |
|        Partner | Partner-Norway |        Entertainment One |      10 |

输出应该是:

| Partner Parent |        Partner |           Advertiser | Revenue |
|----------------|----------------|----------------------|---------|
|        Partner | Partner-Canada |           Air Canada |     500 |
|        Partner | Partner-Canada |     Mazda Motor Corp |     400 |
|        Partner | Partner-Canada |          Ford Motors |     300 |
|        Partner | Partner-Canada |    Land Rover Motors |     200 |
|        Partner | Partner-Canada | Kaspersky Anti-Virus |     100 |
|        Partner | Partner-Canada |            All Other |      50 |
|        Partner | Partner-Norway |             Manulife |     500 |
|        Partner | Partner-Norway |                 CIBC |     400 |
|        Partner | Partner-Norway |           Pfizer Inc |     300 |
|        Partner | Partner-Norway |        TD Bank Group |     200 |
|        Partner | Partner-Norway |     General Electric |     100 |
|        Partner | Partner-Norway |            All Other |      50 |

等等

您可以使用 ROW_NUMBERSUM() 来获得 All Others:

SQL Fiddle

;WITH Cte AS(
    SELECT *,
        RN = ROW_NUMBER() OVER(PARTITION BY [Partner Parent], Partner ORDER BY Revenue DESC)
    FROM [table]
)
SELECT *
FROM(
    SELECT
        [Partner Parent],
        Partner,
        Advertiser,
        Revenue
    FROM Cte
    WHERE RN <= 5

    UNION ALL

    SELECT
        [Partner Parent],
        Partner,
        Advertiser = 'All Other',
        Revenue = SUM(Revenue)
    FROM Cte
    WHERE RN > 5
    GROUP BY 
    [Partner Parent], Partner
)t
ORDER BY 
    [Partner Parent],
    Partner,
    CASE 
        WHEN Advertiser = 'All Other' THEN NULL
        ELSE Revenue
    END DESC