A blog about SQL Server, SSIS, C# and whatever else I happen to be dealing with in my professional life.

Find ramblings

Wednesday, April 21, 2010

Top N producers by X

A quick hit that sounded interesting. @grrl_geek was looking for "I have table of biz divisions. Each div has separate customers. Need to find each division's top 10 customers. I have table of biz divisions. Each div has separate customers. Need to find each division's top 10 customers."

As I'm racing to get this in ahead of others, I'll dispense with the usual cruft. Be sure to know what Ranking function you need to use. See references below.


SET NOCOUNT ON
DECLARE @STUFF TABLE
(
    division int NOT NULL
,   person varchar(50) NOT NULL
,   sales float NOT NULL
)

DECLARE @topN int
SELECT @topN = 3

INSERT INTO
    @STUFF
SELECT 10 AS division, 'Tom 10' AS person, 100.01
UNION ALL SELECT 10 AS division, 'Jerry 10' AS person, 30.30
UNION ALL SELECT 10 AS division, 'Paco 10' AS person, 400.01
UNION ALL SELECT 10 AS division, 'Alfred 10' AS person, 87.01
UNION ALL SELECT 10 AS division, 'John 10' AS person, 5.01
UNION ALL SELECT 10 AS division, 'Paul 10' AS person, 700.11
UNION ALL SELECT 10 AS division, 'George 10' AS person, 700.89
UNION ALL SELECT 10 AS division, 'Ringo 10' AS person, 1.87
UNION ALL SELECT 10 AS division, 'Pierre 10' AS person, 100.01
UNION ALL SELECT 10 AS division, 'Mike 10' AS person, 100.01
UNION ALL SELECT 10 AS division, 'Trevor 10' AS person, 99.99
UNION ALL SELECT 10 AS division, 'Herbie 10' AS person, 18.81
UNION ALL SELECT 10 AS division, 'Tim 10' AS person, 21.01

UNION ALL SELECT 20 AS division, 'Jerry 20' AS person, 30.30
UNION ALL SELECT 20 AS division, 'Paco 20' AS person, 400.01
UNION ALL SELECT 20 AS division, 'Alfred 20' AS person, 87.01
UNION ALL SELECT 20 AS division, 'John 20' AS person, 5.01
UNION ALL SELECT 20 AS division, 'Paul 20' AS person, 700.11
UNION ALL SELECT 20 AS division, 'George 20' AS person, 700.89
UNION ALL SELECT 20 AS division, 'Ringo 20' AS person, 1.87
UNION ALL SELECT 20 AS division, 'Pierre 20' AS person, 200.01
UNION ALL SELECT 20 AS division, 'Mike 20' AS person, 200.01
UNION ALL SELECT 20 AS division, 'Trevor 20' AS person, 99.99
UNION ALL SELECT 20 AS division, 'Herbie 20' AS person, 18.81
UNION ALL SELECT 20 AS division, 'Tim 20' AS person, 21.01

UNION ALL SELECT 30 AS division, 'Jerry 30' AS person, 30.30
UNION ALL SELECT 30 AS division, 'Paco 30' AS person, 400.01
UNION ALL SELECT 30 AS division, 'Alfred 30' AS person, 87.01
UNION ALL SELECT 30 AS division, 'John 30' AS person, 5.01
UNION ALL SELECT 30 AS division, 'Paul 30' AS person, 700.11
UNION ALL SELECT 30 AS division, 'George 30' AS person, 700.89
UNION ALL SELECT 30 AS division, 'Ringo 30' AS person, 1.87
UNION ALL SELECT 30 AS division, 'Pierre 30' AS person, 300.01
UNION ALL SELECT 30 AS division, 'Mike 30' AS person, 300.01
UNION ALL SELECT 30 AS division, 'Trevor 30' AS person, 99.99
UNION ALL SELECT 30 AS division, 'Herbie 30' AS person, 18.81
UNION ALL SELECT 30 AS division, 'Tim 30' AS person, 21.01
;
WITH RANKED AS
(
    SELECT
        S.division
    ,   S.person
    ,   S.sales
    ,   RANK() OVER (PARTITION BY S.division ORDER BY S.sales DESC) AS sales_rank
    FROM
        @STUFF S
)
SELECT
    R.*
FROM
    RANKED R
WHERE
    R.sales_rank <= @topN

References
http://msdn.microsoft.com/en-us/library/ms189798.aspx

No comments: