SQL Server 2012:根据多个条件选择前n个

时间:2014-03-31 19:35:45

标签: sql sql-server-2012

这里对SQL很陌生 - 非常感谢帮助。我有一个包含RegionMonthMember IDSales的表(每个成员有多个交易)。我只是想根据每个地区,每个月的销售总额来提取前2名成员....所以基本上:

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 

变为:

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 

最终,将有10个地区,我希望每个月按成员排名前5位。

3 个答案:

答案 0 :(得分:2)

您可以使用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;

答案 1 :(得分:2)

如果你担心关系(你可能就像@Conrad Frix指出的那样)你可能更喜欢RANK()到ROW_NUMBER()。

我会借用样本数据,清楚地使用CTE,应用我首选的格式,然后提供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

答案 2 :(得分:0)

我发现使用 TOP 语句更容易

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

结果是:

    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