sql >> Databasteknik >  >> RDS >> Sqlserver

MSSQL Välj topp 10 vinnande poäng, inklusive oavgjort och minst en från varje kategori

Som jag kan se det måste du rangordna dina rader på ett mer sofistikerat sätt, så att poster som är de bästa i varje kategori inkluderas oavsett deras värden, och poster som inte är de översta inkluderas enligt deras övergripande ranking.

Det jag ska föreslå kanske inte är den mest effektiva lösningen, men det borde fungera och, om inget annat kan, kan det inspirera någon annan att komma på något bättre:

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örsta CTE rangordnar rader efter kategorier, vilket låter oss ta reda på vilka bidrag som blir de bästa i sina respektive kategorier. Nästa steg (andra CTE) handlar om att få global ranking, denna gång med hänsyn till om ett bidrag är det bästa i sin kategori eller inte. Kategorin toppvärden får lägre ranking och är därmed säkerställda att inkluderas i slutresultaten. (Naturligtvis måste du se till att antalet kategorier inte är större än antalet distinkta värden du vill ta emot i utdata.)

Här är ett liveexempel på SQL Fiddle att leka med.




  1. Hur man redigerar data i mysql genom en modal

  2. TEMPFILE Offline Fysisk standby

  3. Bästa sättet att lagra XML-data i en MySQL-databas, med vissa specifika krav

  4. Felsökning av CPU-prestanda på VMware