2013-03-16 90 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