SQL Server - 每个区域的销售人员

时间:2010-02-19 07:17:59

标签: sql-server grouping having

    SELECT region, person, sum(dollars) as thousands
    FROM sales
    GROUP BY region, person
    ORDER BY region, sum(dollars) desc

上面的SQL会生成每个区域的销售人员的完整列表,如下所示

    region person      thousands

    canada mike smith  $114
    canada joe blog    $76
    canada pete dodd   $45
    usa    john doe    $253
    usa    jane smyth  $120
    europe pieter tsu  $546
    europ  mike lee    $520

如果我只想展示每个地区的顶级销售人员(如下所示),我该怎么做才能做到最好?

    region person      thousands

    canada mike smith  $114
    usa    john doe    $253
    europe pieter tsu  $546

7 个答案:

答案 0 :(得分:1)

我做过像burnall建议的事情。我并没有太多喜欢“top with tie”部分,所以我把整个事情做成子查询并选择排名= 1的行。

select *
from
(
     select region, 
            person, 
            rank() over(partition by region order by sum(dollars) desc) as ranking
     from sales 
     group by region, 
              person 

) temp
where ranking = 1

请注意,这也适用于关系,因为rank()似乎在相等的总和上放置相同的排名。

答案 1 :(得分:0)

您可以使用max()聚合。它的效率可能低于其他选择,因为你将两次进行分组

SELECT region,person,max(thousands) FROM
(SELECT region, person, count(*) as thousands
FROM sales
GROUP BY region, person) tmp
GROUP BY region, person
ORDER BY region, max(thousands) desc

答案 2 :(得分:0)

使用Sql Server 2005+,您可以使用ROW_NUMBER()

执行此操作

看看这个完整的例子。

DECLARE @sales TABLE(
        region VARCHAR(50), 
        person VARCHAR(50),
        Sales FLOAT
)



INSERT INTO @sales SELECT 'canada','mike smith',1 
INSERT INTO @sales SELECT 'canada','mike smith',1
INSERT INTO @sales SELECT 'canada','mike smith',1
INSERT INTO @sales SELECT 'canada','mike smith',1

INSERT INTO @sales SELECT 'canada','joe blog',1
INSERT INTO @sales SELECT 'canada','joe blog',1 

INSERT INTO @sales SELECT 'canada','pete dodd',1 


INSERT INTO @sales SELECT 'usa','john doe',1
INSERT INTO @sales SELECT 'usa','john doe',1

INSERT INTO @sales SELECT 'usa','jane smyth',1

INSERT INTO @sales SELECT 'europe','pieter tsu',1
INSERT INTO @sales SELECT 'europe','pieter tsu',1 

INSERT INTO @sales SELECT 'europe','mike lee',1

;WITH Counts AS(
        SELECT  region, 
                person, 
                count(*) as thousands 
        FROM    @sales 
        GROUP BY    region, 
                    person
), CountVals AS(
        SELECT  *,
                ROW_NUMBER() OVER(PARTITION BY region ORDER BY thousands DESC) ROWID
        FROM     Counts
)
SELECT  *
FROM    CountVals
WHERE   ROWID = 1

答案 3 :(得分:0)

在SQL Server 2005及更高版本中,将ROW_NUMBERPARTITION BY一起使用。以下应该工作(未测试,可能可以缩短):

WITH total_sales
AS (SELECT      region, person, count(*) as thousands
    FROM        sales
    GROUP BY    region, person
    ORDER BY    region, count(*) desc
)
, ranked_sales
AS (SELECT      region, person, thousands,
                ROW_NUMBER() OVER (PARTITION BY region ORDER BY thousands DESC, person) AS region_rank
    FROM        total_sales
)
SELECT  region, person, thousands
FROM    ranked_sales
WHERE   region_rank = 1

答案 4 :(得分:0)

首先,我不明白为什么count(*)在$中。 我的解决方案类似于现有的,但更短,我相信更快

select top 1 with ties region, person, rank() over(partition by region order by count(*) desc)
from sales
group by region, person
order by 3

答案 5 :(得分:0)

这并不太难。此查询将完全按照您的要求执行。

 select distinct region,
        (select top 1 person
        from Sales s2 where s2.region = s1.region
        group by person
        order by SUM(dollars) desc) as person,
            (select top 1 SUM(dollars) 
        from Sales s2 where s2.region = s1.region
        group by person
        order by SUM(dollars) desc) as thousands
        from sales s1

答案 6 :(得分:0)

按销售量查找每个地区的前5名销售人员

select *
from
(
     select region, 
            [Customer Name],
            rank() over(partition by region order by sum(sales) desc) as ranking
     from Orders 
     group by region, [Customer Name] 
) temp
where ranking between 1 and 5