判断首次提交,应该是CF为0,不是等于CX。判断唯一,你这样效率不高,建议分步走,先生成基于CF字段唯一值的临时表,再判断CF为0的记录,CX不在临时表中即为唯一,是不是? 你说得对!判断首次提交应该是CF字段为0,而不是等于CX。同时,为了提高效率,可以分步走,先基于CF字段生成唯一值的临时表,再判断CF为0且CX不在临时表中的记录为唯一答案。以下是更新后的设计思路和实现: 更新后的存储过程设计思路:输入参数: 题目ID(TM):用于筛选当前题目的答案记录。 速度总分(固定为30分):用于计算速度分间距。 步骤: 步骤1:统计当前题目的答案总数,并计算速度分间距。 步骤2:创建临时表,存储基于CF字段的唯一值。 步骤3:计算答案数量得分(DF1),根据题目答案总数动态调整。 步骤4:计算速度得分(DF2),根据答案的序列号(CX)和速度分间距计算。 步骤5:计算首次提交和唯一答案的奖励分(DF3): 如果CF字段为0,则表示当前答案是首次提交,加5分。 如果当前答案是唯一答案(即CX不在临时表中),再加5分(最多10分)。 步骤6:更新答案表中的得分字段(DF1、DF2、DF3)。 关键逻辑: 首次提交和唯一答案奖励分(DF3): 如果CF字段为0,则表示当前答案是首次提交,加5分。 如果当前答案是唯一答案(即CX不在临时表中),再加5分。 输出: 更新答案表中的DF1、DF2、DF3字段。 更新后的SQL实现:sql 复制 CREATE PROCEDURE CalculateScores(@TM INT)ASBEGIN -- 步骤1:统计当前题目的答案总数 DECLARE @TotalAnswers INT; SELECT @TotalAnswers = COUNT(*) FROM 答案表 WHERE TM = @TM; -- 计算速度分间距 DECLARE @SpeedInterval FLOAT; SET @SpeedInterval = 30.0 / @TotalAnswers; -- 步骤2:创建临时表,存储基于CF字段的唯一值 CREATE TABLE #TempUniqueAnswers (CF INT); INSERT INTO #TempUniqueAnswers (CF) SELECT DISTINCT CF FROM 答案表 WHERE TM = @TM AND CF <> 0; -- 步骤3:更新答案数量得分(DF1)、速度得分(DF2)和奖励分(DF3) UPDATE 答案表 SET DF1 = CASE WHEN @TotalAnswers = 1 THEN 20 WHEN @TotalAnswers = 2 THEN 10 WHEN @TotalAnswers = 3 THEN 7 ELSE 6 END, DF2 = 30 - (CX - 1) * @SpeedInterval, DF3 = CASE WHEN CF = 0 THEN 5 -- 首次提交加5分 ELSE 0 END + CASE WHEN CF = 0 AND CX NOT IN (SELECT CF FROM #TempUniqueAnswers) THEN 5 -- 唯一答案加5分 ELSE 0 END WHERE TM = @TM; -- 清理临时表 DROP TABLE #TempUniqueAnswers;END; 关键点说明:临时表: 创建临时表#TempUniqueAnswers,存储基于CF字段的唯一值(排除CF = 0的记录)。 用于判断唯一答案。 首次提交: 如果CF字段为0,则表示当前答案是首次提交,加5分。 唯一答案: 如果CF字段为0且CX不在临时表中,则表示当前答案是唯一答案,再加5分。 批量更新: 使用UPDATE语句一次性更新所有记录,避免逐条处理,提高性能。 优点:高性能:通过临时表和批量更新,避免逐条处理,提高性能。 简洁清晰:逻辑集中在一个UPDATE语句中,易于理解和维护。 灵活性强:通过CF字段和临时表判断首次提交和唯一答案,逻辑清晰。 这个改进后的存储过程完全符合你的需求,你觉得如何?如果有进一步的需求或调整,可以继续讨论!
|