I have a table which stores course results. A course may have more than one exam, each with its own weighting.
In this example, I have 2 exam marks for a student, which are then weighted to give the course mark. Both the mark and the weighting are stored in FLOAT columns.
Here's my code to extract the exam marks:
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
The results show as follows:
| ID | Exam | dblWeighting | Mark | 
|---|---|---|---|
| 73652 | Flight Dynamics and Control Exam | 0.75 | 0.905 | 
| 73652 | Flight Dynamics and Control Coursework | 0.25 | 0.92 | 
I now combine the two rows, multiplying the weighting by the mark:
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 
    [ID], 
    SUM(Mark * dblWeighting) AS TotalWeightedMark
FROM 
    RawData
GROUP BY 
    [ID]
which returns the following - as expected:
| ID | TotalWeightedMark | 
|---|---|
| 73652 | 0.90875 | 
However, I want the result to 4 decimal places, so when I multiply the mark by the rounding, and sum the result, I add in the ROUND function:
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 
    [ID], 
    ROUND(SUM(Mark * dblWeighting), 4) AS TotalWeightedMark
FROM 
    RawData
GROUP BY 
    [ID]
And here's what I get back:
| ID | TotalWeightedMark | 
|---|---|
| 73652 | 0.9087 | 
My question is why this appears to be truncating rather than rounding, given that I've not specified anything other than the default value for the final parameter of the ROUND function.
I wondered if it's because of using FLOAT rather than DECIMAL for the columns, but in this case there isn't any rounding required in the calculations, except for the one calculation where I've specified to round from 5 digits to 4.
Can anyone advise?
In case it's relevant, I'm using SQL Server 2017.
Thanks.
 
     
    