我有一个存储课程成绩的表。一门课程可以有多个考试,每个考试都有自己的权重。
在这个例子中,我有一个学生的两个考试分数,然后将其加权得到课程分数。标记和权重都存储在FLOAT列中。
下面是我提取考试分数的代码:
WITH RawData AS
(
SELECT
lngRelatedScoreID AS [ID],
cc.strName AS Exam,
cc.dblWeighting,
sci.dblModeratedComponentScorePercent AS Mark
FROM
tblStudentComponentInformation sci
INNER JOIN
tblCourseComponents cc ON sci.lngExamID = cc.lngExamID
WHERE
sci.lngRelatedScoreID IN (73652)
)
SELECT * FROM RawData
结果如下:
ID正如在评论中提到的,"问题"是数据类型,而不是表达式。
如果我们看下面的例子:
SELECT [ID],
SUM(FloatWeighting*FloatMark) AS Float,
SUM(Decimalweighting*DecimalMark) AS Decimal,
CONVERT(decimal(18,12),SUM(FloatWeighting*FloatMark)) AS ConvertedFloat,
ROUND(SUM(FloatWeighting*FloatMark),4) AS RoundedFloat,
ROUND(SUM(Decimalweighting*DecimalMark),4) AS RoundedDecimal
FROM (VALUES(73652,'Flight Dynamics and Control Exam ',CONVERT(float,0.75),CONVERT(decimal(3,2),0.75),CONVERT(float,0.905),CONVERT(decimal(4,3),0.905)),
(73652,'Flight Dynamics and Control Coursework',CONVERT(float,0.25),CONVERT(decimal(3,2),0.25),CONVERT(float,0.92),CONVERT(decimal(4,3),0.92)))V(ID,Exam,FloatWeighting,DecimalWeighting,FloatMark,DecimalMark)
GROUP BY ID;
如果运行此命令,将得到以下结果:
ID Float Decimal ConvertedFloat RoundedFloat RoundedDecimal
----- ------- ------- -------------- ------------ --------------
73652 0.90875 0.90875 0.908750000000 0.9088 0.90880
注意,四舍五入的decimal
值提供了您期望的值,但四舍五入的float
没有。这是因为,正如在评论中讨论的那样,浮点值不是基数为10的值,而是基数为2的值。因此float
值0.90875
实际上不是0.90875
,而是0.908749999999999946709294817992486059665679931640625
。注意,这个值实际上(只是)小于0.90875
。
因此,当您应用函数ROUND
时,使用上面的值,当您将该值ROUND
到小数点后4位时,0.9087
是正确答案。
ALTER
,使列成为decimal
。例如,它可能是:
ALTER TABLE dbo.tblCourseComponents ALTER COLUMN Mark decimal(4,3);
请注意,您需要为实际值使用适当的比例和精度。
如果你不能改变数据类型,或者至少现在不能,那么你可以先显式地将值转换为decimal
,然后再进行算术运算。例如:
ROUND(SUM(CONVERT(decimal(3,2),Weighting)*CONVERT(decimal(4,3),Mark)),4)
同样,请确保您使用适当的精度和比例为您的数据。