Sql 从复杂函数中获取ISNULL
我有一个SQL表UDF,它从20天移动平均值中获得标准偏差。。。其计算依据的表格是:Tickers[date]datetime[close]numeric7,2 该函数计算一个表GetStDev[date]datetime,stddev numeric7,2 由于STDEV calc?…的原因,stddev列的最后一行始终为空?。。。我需要用前一行[date]-1中的值替换最后一行中的空值。。。但是在这样做的过程中,我是否需要计算整个查询两次并从xxx中选择TOP 1 stddev,即使如此,我也不知道如何编写这么长的SQL语句。。。以下是我的在线表格UDF:Sql 从复杂函数中获取ISNULL,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个SQL表UDF,它从20天移动平均值中获得标准偏差。。。其计算依据的表格是:Tickers[date]datetime[close]numeric7,2 该函数计算一个表GetStDev[date]datetime,stddev numeric7,2 由于STDEV calc?…的原因,stddev列的最后一行始终为空?。。。我需要用前一行[date]-1中的值替换最后一行中的空值。。。但是在这样做的过程中,我是否需要计算整个查询两次并从xxx中选择TOP 1 stddev,即使如此,我
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
)
首先,在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)
除非您测试了您的版本并发现它更快
除此之外,您还可以用多语句表值函数替换它。例如:
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
您可以编写一个UNION ALL查询来追加最后一行,也可以使用存储过程使用表存储设置并使用最后一个结果更新最后一行。
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