我有這樣一個數據表:來自行而不是列返回(IRR)的TSQL內部收益率
Group ID M0 M1 ... M20
------------------------------------
1 1 10 -2 ... 54
1 2 -8 10 ... -20
2 6 -10 12 ... 0
2 4 45 52 ... 0
2 5 12 102 ... 0
我被集團分組我的數據,像這樣:
SELECT Group
, round(sum(M0+M1+M2+...+M20)/count(ID),2) as profit
, round(sum(M0),2) as M0
, round(sum(M1),2) as M1
, ...
, round(sum(M20),2) as M20
FROM
data_table
GROUP BY
Group
什麼我需要添加的是基於M0到M20列的IRR。
我發現一個IRR函數看起來像這樣:
CREATE FUNCTION [dbo].[ufn_IRR]
(
@strIDs VARCHAR(8000),
@guess DECIMAL(30,10)
)
RETURNS DECIMAL(30, 10)
AS
BEGIN
DECLARE @t_IDs TABLE (
id INT IDENTITY(0, 1),
value DECIMAL(30, 10)
)
DECLARE @strID VARCHAR(12),@sepPos INT,@NPV DECIMAL(30, 10)
SET @strIDs = COALESCE(@strIDs + ',', '')
SET @sepPos = CHARINDEX(',', @strIDs)
WHILE @sepPos > 0
BEGIN
SET @strID = LEFT(@strIDs, @sepPos - 1)
INSERT INTO @t_IDs (value) SELECT (CAST(@strID AS DECIMAL(20, 10))) WHERE ISNUMERIC(@strID) = 1
SET @strIDs = RIGHT(@strIDs, DATALENGTH(@strIDs) - @sepPos)
SET @sepPos = CHARINDEX(',', @strIDs)
END
SET @guess = CASE WHEN ISNULL(@guess, 0) <= 0 THEN 0.00001 ELSE @guess END
SELECT @NPV = SUM(value/POWER(1 + @guess, id)) FROM @t_IDs
WHILE @NPV > 0
BEGIN
SET @guess = @guess + 0.00001
SELECT @NPV = SUM(value/POWER(1 + @guess, id)) FROM @t_IDs
END
RETURN @guess
END
使用示例如下:
SELECT dbo.ufn_IRR('-4000,1200,1410,1875,1050',0.00001)
但在我的情況下,我想,以避免從我的列上創建的字符串,如這個:
SELECT dbo.ufn_IRR(
cast(round(sum([M0]), 2) AS NVARCHAR)+','
+cast(round(sum([M1]), 2) AS NVARCHAR)+','
+cast(round(sum([M2]), 2) AS NVARCHAR)+','
+cast(round(sum([M3]), 2) AS NVARCHAR)+','
+cast(round(sum([M4]), 2) AS NVARCHAR)+','
+...+','
+cast(round(sum([M20]), 2) AS NVARCHAR)
,0.00001)
我認爲這是毫無意義的首先創建一個字符串,然後在函數切它成表。
我想修改IRR函數所以比我可以通過我的專欄,但我沒有想法,我應該怎麼做:/
我這樣做的方式,它變得非常複雜,Unpivot和可能的表變量。你必須能夠處理任何表中的任何值,或者你是否只能處理那些特定表中的特定列? –
現在我需要處理該表的最後21列 - 從Mo到M20。我將擔心未來的通用功能。現在只有這一個:) – Misiu
呃。 。 。你有沒有考慮重寫函數,以便在不解析它們的情況下獲取參數? –