SQL2005の2つのソリューションは次のとおりです。私がこれまでに見た他のものは、2つの売上高が同じである場合、正しいデータを返さない可能性があります。しかし、それはあなたのニーズに依存します。
1つ目はRow_Number()関数を使用し、すべての行が売上の低いものから高いものへとランク付けされます(その後、いくつかのタイブレークルール)。次に、結果を得るために店舗ごとに最高ランクが選択されます。
Row_Number関数にPartionBy句を追加してみたり(BOLを参照)、「in」句の代わりに内部結合を使用して調査したりできます。
2つ目は、Turnkeyのアイデアを借りて、再びランク付けしますが、ストアごとに分割するため、最初にランク付けされたものを選択できます。Dense_Rankは、2つの同じ行に同じランクを与える可能性があるため、ストアと部門が一意でない場合は、2つの行を返す可能性があります。Row_numberを使用すると、番号はパーティション内で一意になります。
注意すべき点は、これは遅いかもしれませんが、他のソリューションの1つでのサブクエリよりも、ほとんどのデータセットで高速になるということです。このソリューションでは、クエリを1行に1回実行する必要があり(並べ替えなどを含む)、多くのクエリが発生する可能性があります。
他のクエリでは、店舗あたりの最大売上を選択してその方法でデータを返し、2つの部門の売上が同じである場合は、店舗の重複行を返します。最後のクエリはこれを示しています。
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