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