首页 > 解决方案 > 如何为每个类别选择前 n 条记录

问题描述

我正在尝试编写一个连接 2 个表的查询,并将给我前 5 个名称以及他们在某个日期范围(即 2016 年 1 月 1 日至 2017 年 12 月 31 日)之间的某个位置销售的商品数量。

根据我一直在研究的内容,这就是我想出的:

SELECT
    EmployeeName, 
    COUNT(ID) AS 'Number of Deals', 
    CompanyNumber
FROM
(
    SELECT
        EmployeeName, 
        DealID, 
        CompanyNumber,
        ROW_NUMBER() OVER (PARTITION BY CompanyNumber ORDER BY DealID) AS rn
    FROM Deal
    JOIN DealEmployee
        ON Deal.DealID. =DealEmployee.DealID AS T
    WHERE
        Deal.Status = 2 AND
        Date BETWEEN '2016-01-01' AND '2017-12-31' AND
        EmployeeName != '' AND T.rn <=5 

我希望得到以下结果:

在此处输入图像描述

我是个新手,我知道我的语法不正确。给予任何帮助将不胜感激

标签: sqlinner-joinssmsrow-numberderived-table

解决方案


未经测试,但我会尝试类似:

with
basedata as (    
select EmployeeName
     , CompanyNumber
     , COUNT(ID) as Number_of_Deals
  from Deal
  join DealEmployee
    on Deal.DealID = DealEmployee.DealID    
 where Deal.Status = 2
   and Date between '2016-01-01' and '2017-12-31'
   and EmployeeName !=''
 group by EmployeeName
        , CompanyNumber 
)
,
basedata_with_rank as (
select t.*
     , row_number() over (partition by CompanyNumber order by Number_of_Deals desc) rn
  from basedata
)
select *
  from basedata_with_rank
 where rn <= 5
 order by CompanyNumber
        , Number_of_Deals desc

使用 CTE 使查询通常更具可读性。顺便说一句:我会避免给列命名为“日期”(保留字),并且我总是为我的列使用限定名称。也许使用分析函数 rank 或dense rank 会更合适,但 row_number 也应该起作用。


推荐阅读