Seperti yang saya lihat, Anda perlu memberi peringkat pada baris Anda dengan cara yang lebih canggih, sehingga entri yang teratas di setiap kategori disertakan terlepas dari nilainya, dan entri yang bukan yang teratas disertakan menurut keseluruhannya. peringkat.
Apa yang akan saya sarankan mungkin bukan solusi yang paling efisien, tetapi harus berhasil dan, jika tidak ada yang bisa, mungkin menginspirasi orang lain untuk membuat sesuatu yang lebih baik:
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
;
CTE pertama adalah memberi peringkat pada baris berdasarkan kategori, sehingga memungkinkan kami mengetahui entri mana yang menjadi yang teratas di kategorinya masing-masing. Langkah selanjutnya (CTE kedua) adalah tentang mendapatkan peringkat global, kali ini dengan mempertimbangkan apakah sebuah entri adalah yang teratas dalam kategorinya atau tidak. Nilai teratas kategori menerima peringkat yang lebih rendah dan dengan demikian dipastikan disertakan dalam hasil akhir. (Tentu saja, Anda perlu memastikan bahwa jumlah kategori tidak lebih besar dari jumlah nilai berbeda yang ingin Anda terima dalam output.)
Berikut adalah contoh langsung di SQL Fiddle untuk bermain bersama.