views:

70

answers:

2

I have a table where I need to get the top n highest amount items for each Category.

Category Item  InventoryCount
-------  ----- ------------- 
Beverage  milk    3  
Beverage  water   2 
Beverage  beer    9 
Utensil   fork    7 
Utensil   spoon   2 
Utensil   knife   1 
Utensil   spork   4 

My desired output is the highest Inventory of the topmost 2 Categories.

Category Item  InventoryCount
-------  ----- ------------- 
Beverage  beer   9 
Beverage  milk   3 
Utensil   fork   7 
Utensil  spork   4 
+1  A: 

This should work for you. If it doesn't satisfy your requirements, post back what you need. Your original desire was to have 25, so you'd simply modify the last clause to be HAVING COUNT(*) <= 25

SELECT  a.item, 
        a.category, 
        a.inventorycount, 
        COUNT(*) AS ranknumber
FROM inv AS a 
INNER JOIN inv AS b 
     ON (a.category = b.category) 
     AND (a.inventorycount <= b.inventorycount)
GROUP BY  a.category, 
          a.item, 
          a.inventorycount
HAVING COUNT(*) <= 2
ORDER BY a.category, COUNT(*) DESC

If you wanted to select more columns from the table, simply add them to the SELECT and `GROUP BY' clauses.

Only when you want to expand the "TOP n for each Category, foo, bar", then you would add those columns to the INNER JOIN clause as well.

--show the top 2 items for each category and year.
SELECT  a.item, 
        a.category, 
        a.year,
        a.inventorycount, 
        COUNT(*) AS ranknumber
FROM inv AS a 
INNER JOIN inv AS b 
     ON (a.category = b.category) 
     AND (a.year = b.year) 
     AND (a.inventorycount <= b.inventorycount)
GROUP BY  a.category, a.item, a.year, a.inventorycount
HAVING COUNT(*) <= 2
ORDER BY a.year, a.category, COUNT(*) DESC
p.campbell
Thanks! that worked wonderfully!I know I am asking for much but say that I added two more columns: Location and year.Would it be possible in the same query to group the top 2 categories by each location and year?
Rick
When I add "ON (a.year = b.year)" I get a syntax error.
Rick
@Rick: that was a copy/paste error. Should be `AND`. Corrected above.
p.campbell
I am getting a bit inconsistent output.I have only 2 years (2009, 2010), so I should get 4 records per category, but sometimes I get 3.In the original query there more than 2 records per category per year.
Rick
You're aware that Jet/ACE TOP N returns ties? That is, if the top 3 values a 1, 2 and 3, and there are two records with 3, you'll get 4 records in your result?
David-W-Fenton
A: 

If the order is not important:

SELECT * FROM inv
ORDER BY InventoryCount DESC LIMIT 5
Allan
@Allan: this answer won't solve the business problem. Also note: Microsoft Access doesn't support the `LIMIT` clause.
p.campbell
Don't post answers with SQL that doesn't work for the database engine stated in the question -- -1.
David-W-Fenton
Apologies for posting unsupported SQL to an MS Access question. But correct me if I'm wrong, but in Access there is similar functionality: "select top 5 * from ..."
Allan
I don't believe that TOP N and LIMIT N are equivalent.
David-W-Fenton