2013-03-16 89 views
1

我读过“如果你在sql中使用循环,你可能做错了”,这导致我在这里。在这个问题之前,还有一些背景。我有以下的数据库结构:替代SQL中的“循环”?

  • “用户” 具有:
    • 用户ID INT IDENTITY(PK)
    • 可靠性浮子
  • “UserSubmissions” 具有:
    • 值浮(FK)(PK)
    • SubmissionID(FK)(PK)
    • 时间戳的日期时间(PK)
  • “GlobalSubmissions” 具有:
    • IdealValue浮
    • SubmissionID(PK)

思考的GlobalSubmissions作为一个表格,其中包含用户理想的理想值,用户应该提交。 UserSubmissions是一个包含用户提交的值的表格。

我写了通过比较用户的“提交” s到一个单一的,特定的“globalSubmission”估计用户的可靠性的功能:

CREATE FUNCTION dbo.GetUserReliabilityForSubmission(@userID int, @submissionID int) 
RETURNS float 
AS 
BEGIN 

    DECLARE @userAverageValue float, 
    @idealValue float; 

    SET @userAverageValue = (
     SELECT AVG (Value) 
      FROM UserSubmissions 
     WHERE (UserID = @userID AND SubmissionID = @submissionID)); 

    SET @idealValue = (
     SELECT IdealValue 
     FROM Submission 
     WHERE (SubmissionID = @submissionID)); 

    RETURN 1 - ABS(@userAverageValue - @idealValue); 
END 

这工作,但它计算用户的基于可靠性只有一个特定的提交ID。如果我想计算用户的“全局”可靠性,我需要使用一个循环遍历用户提交过的所有不同的SubmissionID,并在其上运行该过程。

在这种情况下是否有一个很好的选择使用循环?

+0

程序是否返回您期望的内容?我对WHERE(UserID = @userID AND SubmissionID = @submissionID)条件中使用'@ submissionID'有点怀疑...... – dasblinkenlight 2013-03-16 11:24:41

回答

2
SELECT d.UserID, 1 - AVG(ABS(d.avg - d.IdealValue)) 
FROM (
    SELECT us.UserID, gs.SubmissionID, gs.IdealValue, AVG(us.Value) as avg FROM UsersSubmissions us 
    JOIN GlobalSubmissions gs ON gs.SubmissionID = us.SubmissionID 
    GROUP BY us.UserID, gs.SubmissionID, gs.IdealValue) d 
GROUP BY d.UserId 

工作例如:http://sqlfiddle.com/#!6/8d880/8

不过,我会说这是没有定义的可靠性好方法。我想你应该考虑将其更改为类似的东西:

SELECT d.UserID, 1 - AVG(ABS(d.avg - d.IdealValue)/ABS(d.IdealValue)) 
FROM (
    SELECT us.UserID, gs.SubmissionID, gs.IdealValue, AVG(us.Value) as avg FROM UsersSubmissions us 
    JOIN GlobalSubmissions gs ON gs.SubmissionID = us.SubmissionID 
    GROUP BY us.UserID, gs.SubmissionID, gs.IdealValue) d 
GROUP BY d.UserId 

而且和示例:http://sqlfiddle.com/#!6/8d880/14

有什么变化?相对于价值本身,错误。有说是x = 5,当它实际上是并且说x = 500当它是之间有区别。

+0

谢谢。很好的答案! – David 2013-03-16 14:45:41