Jak widzę, musisz uszeregować swoje wiersze w bardziej wyrafinowany sposób, aby wpisy, które znajdują się na szczycie w każdej kategorii, były uwzględniane niezależnie od ich wartości, a wpisy, które nie są najwyższymi, były uwzględniane według ich ogólnej rankingi.
To, co zamierzam zasugerować, może nie jest najskuteczniejszym rozwiązaniem, ale powinno działać, a jeśli nic innego nie może, może zainspirować kogoś innego do wymyślenia czegoś lepszego:
WITH ranked1 AS (
SELECT
*,
RankByCategory = DENSE_RANK() OVER (
PARTITION BY CategoryID
ORDER BY Score DESC
)
FROM YourTable
),
ranked2 AS (
SELECT
*,
FinalRank = DENSE_RANK() OVER (
ORDER BY
CASE RankByCategory WHEN 1 THEN 1 ELSE 2 END,
Score DESC
)
FROM ranked1
)
SELECT
EntryID,
CategoryID,
Score
FROM ranked2
WHERE FinalRank <= @top_n
;
Pierwsze CTE to ranking wierszy według kategorii, dzięki czemu możemy dowiedzieć się, które wpisy stają się najlepszymi w swoich kategoriach. Kolejny krok (drugi CTE) to uzyskanie globalnych rankingów, tym razem z uwzględnieniem tego, czy wpis jest najlepszy w swojej kategorii, czy nie. Najwyższe wartości kategorii otrzymują niższe rankingi, dzięki czemu mają pewność, że zostaną uwzględnione w ostatecznych wynikach. (Oczywiście musisz upewnić się, że liczba kategorii nie jest większa niż liczba odrębnych wartości, które chcesz otrzymać w wyniku).
Oto przykład na żywo w SQL Fiddle do zabawy.