2015-12-15 5 views
0

Я создаю онлайн-конкурс, в котором абитуриенты назначаются судье, и этот судья решает, переходят ли они к следующему раунду.Обнаружение TOP 5 из B для каждой записи в A

После того, как первый раунд закрывается, второй раунд получают в базе данных следующим образом:

Каждый участник/участник, который пропускается через округлить 2 выделяется 5 судей. Эти судьи должны распределяться в зависимости от того, сколько участников уже выделено им. Другими словами, каждый судья должен иметь такое же количество людей, чтобы судить во втором раунде.

В настоящее время у меня есть следующий оператор SQL в хранимой процедуре, которая называется 1 раз, когда конкуренция перемещается в раунд 2:

INSERT INTO recEntrantStatus (entrantId, roundId, judgeId, notified, voted, enterNextRound) 
SELECT 
    r.entrantId, 
    (@input + 1), 
    j.Id /*Now getting tblJudges Id*/, -- fixed name 
    0, 
    0, 
    0 
FROM recEntrantStatus r 
-- Get all of the judges 
    CROSS JOIN (SELECT TOP(5) MEM.Id, ISNULL(ES.EntrantCount, 0) EntrantCount 
       FROM recMembers MEM 
       LEFT JOIN 
       (
        SELECT judgeid, COUNT(judgeid) AS 'EntrantCount' -- name this 
        FROM recEntrantStatus 
        WHERE roundId = 1 
        GROUP BY judgeid 
       ) ES ON MEM.Id = ES.judgeid 
       WHERE MEM.Privilege = 2 
       ORDER BY EntrantCount) AS j 
WHERE r.roundId = @input 
    AND r.voted = 1 
    AND r.enterNextround = 1 

Однако это только вычисляет 5 судей на один раз и распределяет этих 5 судей каждому участнику. Однако мне действительно нужно, чтобы 5 судей были пересчитаны для каждого участника, перенесенного в раунд 2.

Любые предложения по этому вопросу будут оценены.


EXTRA РАЗЪЯСНЕНИЕ

Таким образом, цель состоит в том, чтобы подсчитать, сколько записей каждый судья имеет в текущем раунде (roundId), а затем вычислить/выбрать 5 судей с наименьшим количеством записей. Затем он должен создать 5 новых записей в таблице «recEntrantStatus» для entrantId, причем каждая запись будет такой же, за исключением столбца «judId», который будет содержать соответствующую идею одного из 5 судей. В общей сложности пять записей, это означает, что каждый участник/участник будет иметь запись для каждого из 5 судей в текущем раунде.

Затем процесс будет повторяться для следующего идентифицированного участника/участника (r.entrantId). Поскольку мы просто добавили 5 новых записей, 5 судей с наименьшим количеством участников/записей будут изменены. Поэтому мы определяем, кто это, прежде чем создавать новую строку в db для каждого из этих 5 судей/участника.


SQL FIDDLE

http://sqlfiddle.com/#!6/426d5

+2

Мне нужно было бы увидеть данные образца, текущие результаты и желаемые результаты, чтобы помочь. Или SQL Fiddle. –

+0

Хорошо, я добавил дополнительную информацию, чтобы уточнить. –

+0

Добавлена ​​ссылка SQL Fiddle –

ответ

1

Ill признать, что я мог бы быть неправильно читают запрос здесь (несколько усталым)

Так как это эффективно расчет, основанный на постоянной смене dataset его не было бы для меня, кажется, быть основанной на множестве операцией.

As сколько Im омерзительно рекомендовать курсоры Я чувствую, что это, вероятно, правильный подход здесь

Курсора каждую строку из recEntrantStatus, которая нуждается в движении вверх круглого и выполнить вставку на основе этой строки в своей очереди ...

EDIT ::

declare @entrant bigint 

DECLARE entrant_cursor CURSOR FOR 
SELECT entrantID 
FROM recEntrantStatus r 
WHERE r.roundId = @input 
AND r.voted = 1 
AND r.enterNextround = 1 

OPEN entrant_cursor 



FETCH NEXT FROM entrant_cursor 
INTO @entrant 

WHILE @@FETCH_STATUS = 0 
    BEGIN 
    INSERT INTO recEntrantStatus (entrantId, roundId, judgeId, notified, voted, enterNextRound) 
SELECT 
    r.entrantId, 
    (@input + 1), 
j.Id /*Now getting tblJudges Id*/, -- fixed name 
0, 
0, 
0 
FROM recEntrantStatus r 
-- Get all of the judges 
CROSS JOIN (SELECT TOP(5) MEM.Id, ISNULL(ES.EntrantCount, 0) EntrantCount 
      FROM recMembers MEM 
      LEFT JOIN 
      (
       SELECT judgeid, COUNT(judgeid) AS 'EntrantCount' -- name this 
       FROM recEntrantStatus 
       WHERE roundId = 1 
       GROUP BY judgeid 
      ) ES ON MEM.Id = ES.judgeid 
      WHERE MEM.Privilege = 2 
      ORDER BY EntrantCount) AS j 
WHERE r.roundId = @input 
AND r.voted = 1 
AND r.enterNextround = 1 
and r.entrantID = @entrant 

FETCH NEXT FROM entrant_cursor 
INTO @entrant 

END 
CLOSE entrant_cursor; 
DEALLOCATE entrant_cursor; 

Извинения за форматирование ...

MS Ссылка для курсоров https://msdn.microsoft.com/en-GB/library/ms180169.aspx

EDIT 2:

Ok была небольшая ошибка в исходном SQL изменить линию от моего решения: ORDER BY EntrantCount) AS J

к ORDER BY ISNULL (ES.EntrantCount, 0)) AS j

Причина в том, что вы заказывали базовый EntrantCount no t, где вы изменили нули до 0

+0

Извините, SQL на самом деле не самый большой набор навыков. Не могли бы вы немного разобраться? Благодарю. –

+0

К сожалению, для каждого цикла все равно выделяется один и тот же набор из 5 судей. Мне нужно пересчитывать его каждый раз. Так что каждая вставка имеет 5 судей с наименьшими записями, связанными с ними. Может быть, вы могли бы немного пройти меня через свой ответ, и я надеюсь, что он отработает это оттуда? Постскриптум Спасибо за помощь до сих пор. –

+1

Hi Phill, который должен делать каждую строку отдельно, но я мог бы сделать опечатку или две там ... в этом случае я использую курсор для очереди абитуриентов, а затем выполняет вставку для каждого участника –