SQL-запрос для поиска победителей в конкурсе - PullRequest
3 голосов
/ 24 мая 2011

У меня есть запрос, который возвращает мне следующие результаты:

  Race   | Candidate | Total Votes | MaxNoOfWinners
    ---------------------------------------------------
    1      | 1         | 5000        | 3
    1      | 2         | 6700        | 3
    2      | 1         | 100         | 3
    2      | 2         | 200         | 3
    2      | 3         | 300         | 3
    2      | 4         | 400         | 3
    ...

Мне было интересно, можно ли написать запрос, который бы возвращал только победителей (на основе MaxNoOfWinners и TotalVotes) для определенной расы. Так что за вышесказанное я бы только вернулся

Race   | Candidate | Total Votes | MaxNoOfWinners
---------------------------------------------------
1      | 1         | 5000        | 3
1      | 2         | 6700        | 3
2      | 2         | 200         | 3
2      | 3         | 300         | 3
2      | 4         | 400         | 3
...

Ответы [ 3 ]

6 голосов
/ 24 мая 2011

Вот решение ... Я не проверял, поэтому могут быть опечатки.Идея состоит в том, чтобы использовать функцию RANK () SQL Server для ранжирования по расам на основе голосов, а не включать те, которые не соответствуют критериям.Обратите внимание, что использование RANK (), а не ROW_NUMBER () будет включать связи в результат.

WITH RankedResult AS
(
  SELECT Race, Candidate, [Total Votes], MaxNoOfWinners, RANK ( )  OVER (PARTITION BY Race ORDER BY [Total Votes] DESC) AS aRank
  FROM Results
)
SELECT Race, Candidate, [Total Votes], MaxNoOfWinners
FROM RankedResult
WHERE aRANK <= MaxNumberOfWinners
2 голосов
/ 24 мая 2011

Вот полный рабочий пример, который предполагает две таблицы гонки и кандидаты

Create Table #Race(Race_id int , MaxNoOfwinners int ) 

INSERT INTO #Race (Race_id , MaxNoOfwinners)
VALUES (1,3), 
       (2,3),
       (3,1)


CREATE TABLE #Candidate (CandidateID int , Race_ID int , Total_Votes int )
INSERT INTO #Candidate (CandidateID  , Race_ID  , Total_Votes  )
VALUES (1,1,5000),
        (2,1,6700),
        (1,2,100),
        (2,2,200),
        (3,2,300),       
        (4,2,400),        
        (1,3,42),
        (2,3,22)


;WITH CTE as (
SELECT 
    RANK() OVER(PARTITION BY race_id ORDER BY  race_id, total_votes DESC ) num,
    CandidateID  , Race_ID  , Total_Votes
From 
    #Candidate)
SELECT * FROM cte inner join #Race r
on CTE.Race_ID = r.Race_id
and num <= r.MaxNoOfwinners

DROP TABLE #Race
DROP TABLE #Candidate

со следующими результатами

num                  CandidateID Race_ID     Total_Votes Race_id     MaxNoOfwinners
-------------------- ----------- ----------- ----------- ----------- --------------
1                    2           1           6700        1           3
2                    1           1           5000        1           3
1                    4           2           400         2           3
2                    3           2           300         2           3
3                    2           2           200         2           3
1                    1           3           42          3           1
0 голосов
/ 24 мая 2011
WITH q0 AS (SELECT qry.*, rank() AS r 
   FROM qry OVER (PARTITION BY race ORDER BY total_votes DESC))
SELECT q0.race, q0.candidate, q0.total_votes FROM q0 WHERE r<=q0.max_winners;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...