Мои 2 решения для SQL 2005 приведены ниже. Другие, которые я вижу до сих пор, могут не возвращать правильные данные, если две цифры продаж совпадают. Хотя это зависит от ваших потребностей.
Первый использует функцию Row_Number (), все строки ранжируются от самых низких до самых высоких продаж (затем некоторые правила разрыва связей). Затем наивысший ранг выбирается для магазина, чтобы получить результат.
Вы можете попробовать добавить предложение Partion By в функцию Row_Number (см. BOL) и / или исследовать использование внутреннего соединения вместо предложения "in".
Второй, заимствуя идею «под ключ», снова ранжирует их, но разделяет по магазинам, поэтому мы можем выбрать первый ранжированный. Dense_Rank, возможно, даст двум одинаковым строкам одинаковый ранг, поэтому, если store и Department не были уникальными, он мог бы вернуть две строки. С Row_number номер уникален в разделе.
Следует помнить, что это может быть медленно, но для большинства наборов данных будет быстрее, чем подзапрос в одном из других решений. В этом решении запрос должен выполняться по одному разу для каждой строки (включая сортировку и т. Д.), Что может привести к большому количеству запросов.
Другие запросы выбирают максимальные продажи для магазина и возвращают данные таким образом, возвращая дубликаты строк для магазина, если два отдела имеют одинаковые продажи. Последний запрос показывает это.
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