I would like to use the top 5 to capture the top 5 for a number of criteria.
The data style is month date, area1, subarea1, sub areas2 etc etc, type, unique identifier for each row.
What I’m trying to do is for each month and for area find the top 5 types.
Sample Data:
Date Division Sub Division ID
31/05/2012 Sales 001
31/05/2012 Sales Call Centre 002
31/05/2012 Sales Call Centre 003
31/05/2012 Sales Store 004
31/05/2012 Marketing 005
31/05/2012 Marketing TV 006
30/04/2012 Sales 001
30/04/2012 Sales Call Centre 002
30/04/2012 Sales Call Centre 003
30/04/2012 Sales Store 004
30/04/2012 Marketing 005
30/04/2012 Marketing TV 006
And so on.
The output I’m after is:
Top 5 at Division level (no consideration of Sub Division) for each month
Top 5 at each Sub-Division level for each month
Sample Output:
Date Top5Areas Volume 31/05/2012 Sales 100 31/05/2012 Marketing 90 31/05/2012 HR 50 30/04/2012 Sales 100 30/04/2012 Marketing 90 30/04/2012 HR 50
And depending on the level the sub division for the respective area:
Date Top5Areas Volume 31/05/2012 Call Centre 100 31/05/2012 Store 90 31/05/2012 HR 50
but with 5 for each group.
I'm not should how to do this and wonder if I'll need to build up the result through a number of queries or whether there is a better way.
Thanks in advance and appreciate your suggestions.
SELECT [TableA].[DisplayVar] AS DisplayVar, [TableB].[Date] AS MonthDate, TableC. [Divison] AS Divison, Volume
FROM (SELECT [TableA].[DisplayVar],
[TableB].[Date],
TableC.[Divison],
Volume
( SELECT COUNT() + 1
FROM ( SELECT [TableA].[DisplayVar], [TableB].[Date], TableC.[Divison], COUNT() AS Volume
FROM ([TableA] INNER JOIN [TableB] ON [TableA].[ID] = [TableB].[ID]) LEFT JOIN TableC ON [TableB].ID = TableC.Descriptor
GROUP BY [TableA].[DisplayVar], [TableB].[Date], TableC.[Divison]
) AS T
WHERE T.[TableB].[Date] = Data.[TableB].[Date]
AND T.Volume > Data.Volume
) AS Rank
FROM ( SELECT [TableA].[DisplayVar], [TableB].[Date], TableC.[Divison], COUNT(*) AS Volume
FROM ([TableA] INNER JOIN [TableB] ON [TableA].[ID] = [TableB].[ID]) LEFT JOIN TableC ON [TableB].ID = TableC.Descriptor
WHERE [TableB].[Date] BETWEEN Date() AND DateADD("m", -12, Date())
GROUP BY[TableA].[DisplayVar], [TableB].[Date], TableC.[Divison]
) AS DATA
) AS Data
WHERE (((Data.Rank)<=5))
ORDER BY [TableB].[Date] DESC , Volume DESC;
The only way I can think of to do a top n per date (Which is what I think you are after) in access is to use a correlated subquery. I think the simplest method is similar to using the
ROW_NUMBER()function in other DBMS, it adds an additional field to your orignal aggregate query giving each division/date a rank, the the outer most where clause limits it to rows where the rank is less than or equal to 5.The downfall (or benefit depending on your requirements) of this is that it does not deal with ties, i.e if you had 10 divisions with the same volume all 10 would be returned, not just 5 of them.
I am not sure if this is exactly what you require, but hopefully will is at least get you going in the right direction.