sql >> Base de Datos >  >> RDS >> Sqlserver

MSSQL Seleccione las 10 mejores puntuaciones ganadoras, incluidos los empates y al menos uno de cada categoría

Como puedo ver, necesita clasificar sus filas de una manera más sofisticada, de modo que las entradas que son las primeras en cada categoría se incluyan independientemente de sus valores, y las entradas que no son las primeras se incluyan de acuerdo con su valor general. clasificaciones.

Lo que estoy a punto de sugerir puede no ser la solución más eficiente, pero debería funcionar y, si nada más puede hacerlo, podría inspirar a alguien a pensar en algo mejor:

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
;

El primer CTE clasifica las filas por categorías, lo que nos permite averiguar qué entradas se convierten en las primeras en sus respectivas categorías. El siguiente paso (segundo CTE) se trata de obtener clasificaciones globales, esta vez teniendo en cuenta si una entrada es la primera en su categoría o no. Los valores principales de la categoría reciben clasificaciones más bajas y, por lo tanto, se garantiza que se incluirán en los resultados finales. (Por supuesto, debe asegurarse de que la cantidad de categorías no sea mayor que la cantidad de valores distintos que desea recibir en la salida).

Aquí hay un ejemplo en vivo en SQL Fiddle para jugar.