SQL Server 使用以表为参数的函数聚合表?

djp7away  于 2022-12-17  发布在  其他
关注(0)|答案(1)|浏览(154)

我有一个3列的表(ID,Date,Value),以及一个接受用户定义的表类型(Date,Value)并返回标量的函数。
如何将表聚合为按ID分组的(ID,function_result)?
我试着将它分解为一个子查询,但是我想不出如何将这两列聚合成一个表类型。
示例表:
| 识别号|日期|价值|
| - ------|- ------|- ------|
| A类|二〇二二年十二月三十一日|-98|
| A类|2023年1月31日|0.16666667美元|
| A类|2023年2月28日|0.15594444美元|
| A类|二〇二三年三月三十一日|0.173055634美元|
| A类|2023年4月30日|0.167905834|
| A类|二零二四年八月三十一日|0.174749476|
| A类|2024年9月30日|0.17518635|
| A类|二〇二四年十月三十一日|0.1756二四三一六|
| A类|二〇二四年十一月三十日|0.176063377美元|
| A类|二〇二四年十二月三十一日|小行星114.2795288|
| B|二〇二二年十二月三十一日|-98|
| B| 2023年1月31日|0.16666667美元|
| B| 2023年2月28日|0.15594444美元|
| B|二〇二三年三月三十一日|0.173055634美元|
| B| 2023年4月30日|0.167905834|
| B|二零二三年五月三十一日|0.168325598美元|
| B|二〇二四年七月三十一日|0.174313692|
| B|二零二四年八月三十一日|0.174749476|
| B| 2024年9月30日|0.17518635|
| B|二〇二四年十月三十一日|0.1756二四三一六|
| B|二〇二四年十一月三十日|0.176063377美元|
| B|二〇二四年十二月三十一日|小行星114.2795288|
预期输出:
| 识别号|XIRR|
| - ------|- ------|
| A类|0.08673649美元|
| B| 0.08849615美元|
功能代码:

CREATE FUNCTION [RE].[XIRR]
(
    @Sample XIRRTable READONLY,
    @Rate DECIMAL(19, 9) = 0.1
)
RETURNS DECIMAL(38, 9)
AS
BEGIN
    DECLARE @X DECIMAL(19, 9) = 0.0,
    @X0 DECIMAL(19, 9) = 0.1,
    @f DECIMAL(19, 9) = 0.0,
    @fbar DECIMAL(19, 9) = 0.0,
    @i TINYINT = 0,
    @found TINYINT = 0

IF @Rate IS NULL
    SET @Rate = 0.1

SET @X0 = @Rate

WHILE @i < 500
    BEGIN
        SELECT  @f = 0.0,
            @fbar = 0.0

        SELECT      @f = @f + [Value] * POWER(1 + @X0, (-theDelta / 365.0E)),
        @fbar = @fbar - theDelta / 365.0E * [Value] * POWER(1 + @X0, (-theDelta / 365.0E - 1))
        FROM    (
                SELECT  [Value],
                    DATEDIFF(DAY, MIN(date) OVER (), date) AS theDelta
                FROM    @Sample
            ) AS d

        SET @X = @X0 - @f / @fbar

        If ABS(@X - @X0) < 0.00000001
        BEGIN
           SET @found = 1
           BREAK;
        END

        SET @X0 = @X
        SET @i += 1
   END

If @found = 1
    RETURN  @X

RETURN NULL
END
GO

我的问题是如何构建要传递到函数中的值表,即,我想为ID为“A”的所有值构建一个表并将其传递进来,然后我想为“B”做同样的事情,等等。

pwuypxnk

pwuypxnk1#

您将必须迭代您拥有的ID,并计算每个ID的值。下面的框架应该足以让您开始,因为我没有足够的细节来确保它的工作。

-- Build a temp table to store the results with one row per Id
select Id, convert(decimal(19,9),null) as Xirr 
into #Result
from MyTable
group by Id;

declare @Id char(1), @Rate decimal(19,9) = 0.1;

declare @InputTable XIRRTable;

-- Loop through the results table while there is still a null value
while exists (select 1 from #Result where Xirr is null) begin
    select top 1 @Id = Id from #Result where Xirr is null;

    -- Pull the values for the current id into the table variable to pass to the function
    insert into @InputTable ([date], [value])
    select [date], [value]
    from MyTable
    where Id = @Id;

    -- Update the value in the results table
    update #Result set
        Xirr = RE.XIRR(@InputTable, @Rate)
    where Id = @Id;

    -- Clear the input table ready for the next run
    delete from @InputTable;
end;

select * from #Result;

drop table #Result;

相关问题