2009-10-29 49 views
0

我有一個SQL表UDF從值的20天移動平均值獲取標準偏差...它的計算表格是:Tickers([date] datetime,[close] numeric(7 ,2))從複雜功能獲取ISNULL

的函數計算表GetStDev([日期]日期時間,STDDEV數字(7,2)。

的STDDEV列的最後一行始終是NULL(由於STDEV計算值?)。 ..我需要用前一行([日期] -1)的值替換最後一行中的NULL值...但是這樣做,我是否已經計算了整個查詢兩次,並從中選擇TOP 1 stddev xxx,甚至所以我不知道如何編寫如此長的SQL語句......這是我的Inline Table UDF:

ALTER FUNCTION GetStdDev 
    (
     @TKR VARCHAR(10) 
    ) 
RETURNS TABLE 
AS 
    RETURN 
    (
     SELECT x.[date], ISNULL(STDEV(y.[Close]),0) stdev 
     FROM Tickers x, Tickers y 
     WHERE x.[DATE] > (SELECT TOP 1 z.[DATE] FROM TICKERS z WHERE z.TICKER = @TKR ORDER BY z.DATE ASC)+20 
     AND (DATEDIFF(day, x.[date], GETDATE()) <= 730) 
     AND x.TICKER = @TKR AND y.TICKER = @TKR 
     AND x.[DATE] BETWEEN y.[DATE]-20 AND y.[DATE] 
     GROUP BY x.DATE 
    ) 
+0

你可以寫一個UNION ALL查詢追加,但最後一條線,或使用#表最後一排保存設置並更新與最後的結果,使用存儲過程。 – 2009-10-29 20:01:17

回答

1

首先,你的WHERE子句中,應更換此:

-- reformatted for readability 
WHERE x.[DATE] > (
      SELECT TOP 1 z.[DATE] FROM TICKERS z 
      WHERE z.TICKER = @TKR ORDER BY z.DATE ASC 
     )+20 
    AND (DATEDIFF(day, x.[date], GETDATE()) <= 730) 

有了這個:

WHERE x.[DATE] > (
      SELECT DATEADD(DAY,20,MIN(z.[DATE])) 
      FROM TICKERS z WHERE z.TICKER = @TKR 
     ) 
    AND x.[DATE] > DATEADD(DAY,-731,GETDATE()) 

除非您測試版本,並發現它是更快。

除此之外,您可以用多語句表值函數替換它。例如:

CREATE FUNCTION dbo.GetStdDev (@TKR VARCHAR(10)) 
RETURNS @results TABLE (
    dayno SMALLINT IDENTITY(1,1) PRIMARY KEY 
, [date] DATETIME 
, [stdev] FLOAT 
) 
AS BEGIN 

    DECLARE @min_sysdate DATETIME, @min_tkrdate DATETIME, @rowcount SMALLINT 

    SET @min_sysdate = DATEADD(DAY,-731,GETDATE()) 
    SET @min_tkrdate = DATEADD(DAY,20,(
    SELECT MIN(DATE) FROM TICKERS WHERE TICKER = @TKR)) 

    INSERT @results ([date],[stdev]) 
    SELECT x.[date], ISNULL(STDEV(y.[Close]),0) AS stdev 
    FROM Tickers x 
    JOIN Tickers y ON x.[DATE] BETWEEN DATEADD(DAY,-20,y.[DATE]) AND y.[DATE] 
    WHERE x.[DATE] > @min_tkrdate 
    AND x.[DATE] > @min_sysdate 
    AND x.TICKER = @TKR 
    AND y.TICKER = @TKR 
    GROUP BY x.[DATE] 

    SET @rowcount = @@ROWCOUNT 

    UPDATE @results SET [stdev] = (
    SELECT [stdev] FROM @results WHERE dayno = @rowcount-1) 
    WHERE dayno = @rowcount 

    RETURN 

END 
+0

作品非常感謝你.. – CraigJSte 2009-10-29 23:47:10