2016-03-06 64 views
-1

我想获得pointsEarned列的总和和pointsPossible列的总和。我想把它变成一个百分比。我的问题是,我的SP总是返回0,即使在有给定enrollmentId的行具有先前列的值时也是如此。为什么我的存储过程返回0?

我在做什么错?

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 

这是数据库表:

enter image description here

我执行存储过程和在69的enrollmentId传递,它仍然返回0

+1

我会摆脱回报,并用SELECT – JVM

+0

取代它显示你的'exec'脚本 –

+0

为什么你会摆脱回报,代之以一个' select'?它不能解决问题并完全改变SP的使用。 –

回答

2

整数用分母除法(pointsPossible )大于分子(pointsEarned)返回零。

写为(修订):

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 

正如@ Nick.McDermaid指出,因为这个过程会返回一个标值,它可能更适合将它定义为一个函数,而不是一个存储过程。

1
  1. 使用简单SUM没有OVER

  2. RETURN只能返回int。如果您的百分比低于100%,则整数除法将始终返回0,因此乘以100将返回整个百分比而不是比率。

  3. 检查你没有被零除。

程序

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 
+0

http://stackoverflow.com/questions/19271646/how-to-make-a-sum-without-group-by –

+0

@MitchWheat,我想我知道什么'SUM()OVER()'做。如果我正确地理解了这个问题,OP需要一个普通的总和(一行中的一个数字),而不是多行中的总和。 –

+0

你的意思就像我发布的答案?但关于RETURN的好处只能返回一个int。 –