我正在创建一个在线竞赛,参赛者被分配给一名法官,这位法官决定他们是否进入下一轮。
第一轮结束后,第二轮在数据库中准备如下:
每个参加第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
答案 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的那个