My 2 solutions for SQL 2005 is below. The other ones I can see so far may not return the correct data if two of the sales figures are the same. That depends on your needs though.
The first uses the Row_Number() function, all the rows are ranked from the lowest to the highest sales (then some tie breaking rules). Then the highest rank is chosen per store to get the result.
You can try adding a Partion By clause to the Row_Number function (see BOL) and/or investigate using a inner join instead of an "in" clause.
The second, borrowing on Turnkey's idea, again ranks them, but partitions by store, so we can choose the first ranked one. Dense_Rank will possibly give two identical rows the same rank, so if store and department were not unique, it could return two rows. With Row_number the number is unique in the partition.
Some things to be aware of is that this may be slow, but would be faster for most data sets than the sub-query in one of the other solutions. In that solution, the query would have to be run once per row (including sorting etc), which could result in a lot of queries.
Other queries the select the max sales per store and return the data that way, return duplicate rows for a store if two departments happen to have the same sales. The last query shows this.
DECLARE @tbl as TABLE (store varchar(20), department varchar(20), sales int)
INSERT INTO @tbl VALUES ('Toronto', 'Baskets', 500)
INSERT INTO @tbl VALUES ('Toronto', 'Noodles', 500)
INSERT INTO @tbl VALUES ('Toronto', 'Fish', 300)
INSERT INTO @tbl VALUES ('Halifax', 'Fish', 300)
INSERT INTO @tbl VALUES ('Halifax', 'Baskets', 200)
-- Expect Toronto/Noodles/500 and Halifax/Fish/300
;WITH ranked AS -- Rank the rows by sales from 1 to x
(
SELECT
ROW_NUMBER() OVER (ORDER BY sales, store, department) as 'rank',
store, department, sales
FROM @tbl
)
SELECT store, department, sales
FROM ranked
WHERE rank in (
SELECT max(rank) -- chose the highest ranked per store
FROM ranked
GROUP BY store
)
-- Another way
SELECT store, department, sales
FROM (
SELECT
DENSE_RANK() OVER (PARTITION BY store ORDER BY sales desc,
store desc, department desc) as 'rank',
store, department, sales
FROM @tbl
) tbl
WHERE rank = 1
-- This will bring back 2 rows for Toronto
select tbl.store, department, sales
from @tbl tbl
join (
select store, max(sales) as maxSales from @tbl group by store
) tempTable on tempTable.store = tbl.store
and tempTable.maxSales = tbl.sales