SQL Server 2012: Select Top n based on multiple criteria

谁说胖子不能爱 提交于 2021-02-18 16:59:09

问题


Pretty new to SQL here - help would be much appreciated. I have a table with Region, Month, Member ID, and Sales (with multiple transactions per member). I just want to extract the top 2 members, based on sum of sales, per region, per month....so essentially:

Region   Month     MemberID   Sales
-----------------------------------------
  1      1/1/2013     A       $200 
  2      2/1/2013     B       $300 
  1      1/1/2013     A       $100 
  1      1/1/2013     B        $50 
  2      1/1/2013     D       $500 
  2      2/1/2013     C       $200 

Becomes:

Region  Month   Member ID   Sales
-----------------------------------------
1   1/1/2013    A    $300 
1   1/1/2013    B    $50 
2   1/1/2013    D    $500 
2   1/1/2013    B    $200 

Ultimately, there will be 10 regions, and I'd like to take the top 5 sales by member for each region, each month.


回答1:


You can do this with row_number():

select region, month, MemberId, sales
from (select region, month, MemberId, sum(sales) as sales
             row_number() over (partition by region, month order by sum(sales) desc) as seqnum
      from table t
      group by region, month, MemberId
     ) t
where seqnum <= 2;



回答2:


If you are worried about ties (any you probably are as @Conrad Frix pointed out) you may prefer RANK() to ROW_NUMBER().

I'll borrow sample data, use CTEs for clarity, apply my preferred formatting, and provide a SQLFiddle.

CREATE TABLE MemberSales (
  Region INT
 ,SalesMonth DATETIME
 ,MemberID CHAR(1)
 ,Sales FLOAT
);

INSERT INTO MemberSales VALUES (1, '1/1/2013', 'A', 200);
INSERT INTO MemberSales VALUES (2, '2/1/2013', 'B', 300);
INSERT INTO MemberSales VALUES (1, '1/1/2013', 'A', 100);
INSERT INTO MemberSales VALUES (1, '1/1/2013', 'C', 300);
INSERT INTO MemberSales VALUES (1, '1/1/2013', 'D', 100);
INSERT INTO MemberSales VALUES (1, '1/1/2013', 'B', 50);
INSERT INTO MemberSales VALUES (2, '1/1/2013', 'D', 500);
INSERT INTO MemberSales VALUES (2, '2/1/2013', 'C', 200);

;WITH SalesTotalByMember AS (
  SELECT Region
        ,SalesMonth
        ,MemberID
        ,SUM(Sales) AS Sales
    FROM MemberSales
   GROUP BY Region
           ,SalesMonth
           ,MemberID
), Ranked AS (
  SELECT Region
        ,SalesMonth
        ,MemberID
        ,Sales
        ,RANK() OVER (PARTITION BY Region, SalesMonth ORDER BY SALES DESC) rnk
    FROM SalesTotalByMember
) 
SELECT *
  FROM Ranked
 WHERE rnk <= 2
 ORDER BY region
         ,SalesMonth
         ,rnk



回答3:


I see it's easier to use TOP statement

create table Table1
(
    Region int,
    Month datetime,
    [Member ID] char(1),
    Sales float
);

insert into Table1 values (1, '1/1/2013', 'A', 200);
insert into Table1 values (2, '2/1/2013', 'B', 300);
insert into Table1 values (1, '1/1/2013', 'A', 100);
insert into Table1 values (1, '1/1/2013', 'B', 50);
insert into Table1 values (2, '1/1/2013', 'D', 500);
insert into Table1 values (2, '2/1/2013', 'C', 200);

select Top 5 Region, Month, [Member ID], sum(Sales) As [Total Sales] 
  from table1
group by Region, Month, [Member ID]
order by Region, Month, [Member ID], sum(Sales) desc

Results are:

    REGION  MONTH              MEMBER ID    TOTAL SALES
       1    January, 01 2013    A   300
       1    January, 01 2013    B   50
       2    January, 01 2013    D   500
       2    February, 01 2013   B   300
       2    February, 01 2013   C   200


来源:https://stackoverflow.com/questions/22770604/sql-server-2012-select-top-n-based-on-multiple-criteria

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!