SQLUSA

Microsoft SQL Server 2008 Best Practices

How to find top 5 for each group with OVER PARTITION BY?

 

Execute the following script in Query Editor to find the top 5 salesperson for each product(group). The ROW_NUMBER function in association with OVER PARTITION BY creates a sequence number in descending sales order for each product in the CTE. The main SELECT takes the first 5 in each subset for the final report:

USE AdventureWorks;

 

-- Let a CTE do the hard work

WITH cteTopSales

AS

(SELECT ROW_NUMBER() OVER (PARTITION BY sod.ProductID

 ORDER BY SUM(sod.LineTotal) DESC) As SeqNo

, FirstName +' '+LastName AS [Name]

, ProductName = p.Name

-- Special currency formatting

, '$'+convert(varchar,convert(money,SUM(sod.LineTotal)),1) AS TotalBySalesPerson

, p.ProductNumber

, sod.ProductID

FROM Sales.SalesOrderDetail AS sod

INNER JOIN Production.Product AS p

    ON sod.ProductID = p.ProductID

INNER JOIN Sales.SalesOrderHeader soh

    ON sod.SalesOrderID = soh.SalesOrderID

INNER JOIN Person.Contact c

    ON soh.SalesPersonID = c.ContactID

WHERE soh.SalesPersonID IS NOT NULL

GROUP BY 

      FirstName +' '+LastName,

      sod.ProductID,

      p.ProductNumber,

      p.Name)

 

-- Easy-going main query

SELECT *

FROM cteTopSales cte

WHERE SeqNo <= 5

ORDER BY ProductID, SeqNo

GO

 

 

SQLUSA - The Best SQL Server 2008 Training in the World
 
 
SQLUSA.com Home Page