sql >> Database teknologi >  >> RDS >> Sqlserver

MSSQL Vælg Top 10 vinderresultater, inklusive uafgjorte resultater og mindst én fra hver kategori

Som jeg kan se det, skal du rangere dine rækker på en mere sofistikeret måde, så poster, der er de øverste i hver kategori, inkluderes uanset deres værdier, og poster, der ikke er de øverste, inkluderes i henhold til deres samlede placeringer.

Det, jeg er ved at foreslå, er måske ikke den mest effektive løsning, men det burde virke, og hvis intet andet kan, kan det måske inspirere en anden til at finde på noget bedre:

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
;

Den første CTE rangerer rækker efter kategorier, og lader os således finde ud af, hvilke poster der bliver de bedste i deres respektive kategorier. Næste trin (anden CTE) handler om at opnå globale placeringer, denne gang under hensyntagen til, om en post er den øverste i sin kategori eller ej. Kategoriens topværdier får lavere placeringer og er dermed sikret med i de endelige resultater. (Selvfølgelig skal du sørge for, at antallet af kategorier ikke er større end antallet af distinkte værdier, du ønsker at modtage i outputtet.)

Her er et liveeksempel på SQL Fiddle at lege med.




  1. Tilfældig registrering fra en databasetabel (T-SQL)

  2. Sequelize Find tilhører Mange Association

  3. Multi-tenant Django-applikationer:Ændring af databaseforbindelse pr. anmodning?

  4. Sammenlign DATETIME og DATE ignorerende tidsdel