检测A中每条记录的B中的TOP 5

时间:2015-12-15 15:53:55

标签: sql sql-server tsql stored-procedures

我正在创建一个在线竞赛,参赛者被分配给一名法官,这位法官决定他们是否进入下一轮。

第一轮结束后,第二轮在数据库中准备如下:

每个参加第2轮的参赛者/参赛者将被分配给5名评委。应根据已分配给他们的参赛者数量来分配这些评委。换句话说,每个法官在第二轮中应该有相似数量的人来判断。

目前我在存储过程中有以下SQL语句,当竞争对手转到第2轮时会被调用1次:

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名评委。

对此的任何建议都将不胜感激。

EXTRA CLARIFICATION

因此,目的是计算每个法官对当前轮次(roundId)的记录数,然后计算/选择记录最少的5名裁判。然后它应该在'recEntrantStatus'表中为entrantId创建5个新记录,每个记录是相同的,除了'judgeId'列,它将包含5个评判者之一的相关想法。总共有五个记录,这意味着每个参赛者/参赛者将有5个评委中的每个参赛者的记录。

然后将对下一个确定的参赛者/参赛者(r.entrantId)重复该过程。由于我们刚刚添加了5条新记录,因此参赛者/记录数量最少的5位评委将会发生变化。因此,我们在为这5位评委/参赛者中的每一位在数据库中创建新行之前确定这些是谁。

SQL FIDDLE

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

1 个答案:

答案 0 :(得分:1)

我承认我可能在这里误读了这个请求(有点累)

由于这实际上是基于正在进行的不断变化的数据集的计算,因此它似乎不是基于集合的操作。

尽管我不喜欢推荐Cursors,但我觉得这可能是正确的方法

从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

编辑2:

好的,原始SQL中的一个小错误改变了我的解决方案中的一行:      ORDER BY EntrantCount)AS j

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

原因是你是由底层的EntrantCount订购而不是你将空值更改为0的那个