Reputation: 4698
I am trying to get the sum of the pointsEarned
column and the sum of the pointsPossible
column. I want to turn this into a percentage. My problem is that my SP always returns 0, even when there are rows with the given enrollmentId
that have values for the previous columns.
What am I doing wrong?
ALTER PROCEDURE GetPercentage
@enrollmentId int
AS
BEGIN
DECLARE @pointsEarned int;
DECLARE @pointsPossible int;
SET NOCOUNT ON;
SELECT
@pointsEarned = CAST(SUM(pointsEarned) OVER() AS decimal),
@pointsPossible = CAST(SUM(pointsPossible) OVER() AS decimal)
FROM
Assignments
WHERE
enrollmentId = @enrollmentId
RETURN @pointsEarned / @pointsPossible
END
GO
This is the database table:
I execute the stored procedure and passed in the enrollmentId
of 69 and it still returns 0.
Upvotes: 0
Views: 2573
Reputation: 32695
Use simple SUM
without OVER
.
RETURN
can return only int
. Integer division will always return 0 if your percentage is less than 100%, so multiply by 100 to return whole percents instead of ratio.
Check that you are not dividing by zero.
Procedure
ALTER PROCEDURE GetPercentage
@enrollmentId int
AS
BEGIN
SET NOCOUNT ON;
DECLARE @pointsEarned int;
DECLARE @pointsPossible int;
SELECT
@pointsEarned = SUM(pointsEarned),
@pointsPossible = SUM(pointsPossible)
FROM
Assignments
WHERE
enrollmentId = @enrollmentId
;
RETURN
CASE WHEN @pointsPossible <> 0
THEN 100 * @pointsEarned / @pointsPossible
ELSE 0 END;
END
GO
Upvotes: 2
Reputation: 300549
Integer division with denominator (pointsPossible
) greater than numerator (pointsEarned
) returns zero.
Write as (revised):
ALTER PROCEDURE GetPercentage
@enrollmentId int
AS
BEGIN
SET NOCOUNT ON;
SELECT
Percent = case when sum(pointsPossible) > 0 then (1.0 * sum(pointsEarned)) / sum(pointsPossible) else 0 end
FROM
Assignments
WHERE
enrollmentId = @enrollmentId
GROUP BY
enrollmentId
END
GO
As @ Nick.McDermaid points out, since this procedure return a scalar value, it might be more appropriate to define it as a function rather than a store procedure.
Upvotes: 2