如何在一段时间内为多个对象运行标量函数

Posted

技术标签:

【中文标题】如何在一段时间内为多个对象运行标量函数【英文标题】:How to run a scalar function over a length of time for multiple objects 【发布时间】:2018-01-15 12:49:33 【问题描述】:

您好,我正在尝试使用标量值函数对大量数据进行算术计算。我的源数据格式如下:

----------
ID  PriceDate   Type    Value
1   14/01/2018  Alpha   1.05
1   14/01/2018  Beta    1.07
2   14/01/2018  Alpha   1.03
2   14/01/2018  Beta    1.2
3   14/01/2018  Alpha   1.6
3   14/01/2018  Beta    1.5
1   15/01/2018  Alpha   1.24
1   15/01/2018  Beta    1.23
2   15/01/2018  Alpha   1.29
2   15/01/2018  Beta    1.1
3   15/01/2018  Alpha   1.16
3   15/01/2018  Beta    1.4

完整的数据集有 700 万行+(1900 个唯一 ID,日期从现在到 2011 年)。 数据集不完整的情况也是如此,ID 可能在特定日期具有 alpha 值但没有 beta 值,反之亦然或根本没有。

我正在尝试计算 ID 同时具有 alpha 值和 beta 值的每个单独日期的 (alpha-beta)/beta。

到目前为止,我有一个函数可以针对特定值执行此操作:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE FUNCTION instrument.Calculate (@PriceDateF datetime, @ID bigint)
RETURNS decimal(20,10)
AS
-- Returns ((Alpha-Beta)/Beta)
BEGIN

    Declare @BetaT decimal(20,10)
    Declare @AlphaT decimal(20,10)
    Declare @Result decimal (20,10)

    SELECT @BetaT = Value
    FROM ValueTable I
    WHERE I.PriceDate = @PriceDateF
    AND I.ID = @ID
    AND Type = 'Beta'

    SELECT @AlphaT = Value
    FROM ValueTable I
    WHERE I.PriceDate = @PriceDateF
    AND I.ID = @ID
    AND Type = 'Alpha'

    SELECT @Result = (@AlphaT - @BetaT)/@BetaT

RETURN @Result

END
GO

我的问题是,如何随着时间的推移在“值表”上为每个单独的 ID 运行此函数,以获得每个 ID 每天的结果 (a-b)/b。我不确定如何输入参数以及函数是否应该遍历数据表或任何其他方式来执行它。我也不确定如何处理数据中的空白(某些日期没有值,或者只有 beta 或 alpha 值)。

非常感谢 :) 我正在使用 SQL Server Management Studio 2014

【问题讨论】:

标记您正在使用的 dbms。 (该代码是特定于产品的。) 【参考方案1】:

在您的情况下,join 可能很简单:

select da.pricedate, da.id, da.value as alpha, db.value as beta,
       (da.value - db.value) / db.value
from data da join
     data db
     on da.pricedate = db.pricedate and da.id = db.id and
        da.type = 'Alpha' and
        db.type = 'Beta';

不需要用户定义的函数。

我应该注意,您也可以通过聚合来做到这一点:

select id, pricedate,
       max(case when type = 'Alpha' then value end) as Alpha,
       max(case when type = 'Beta' then value end) as Beta,
       (max(case when type = 'Alpha' then value end) -
        max(case when type = 'Beta' then value end)
       ) / max(case when type = 'Beta' then value end) as calculation
from data
group by id, pricedate;

再一次,用户定义的函数在这里没有用处。

【讨论】:

加入工作完美。我只需要在连接上添加一个附加条件: (续):...AND db.ID = da.ID。除此之外效果很好。谢谢!

以上是关于如何在一段时间内为多个对象运行标量函数的主要内容,如果未能解决你的问题,请参考以下文章

如何从多个标量函数返回 StructArray

如何在一天内为你的实验室做一个网站

如何在一段时间后停止正在运行的方法执行? [复制]

使用 SQL 标量函数的查询如何从 5 分钟内运行到 5 小时

Python中如何在一段时间后停止程序

使用 Big Query,我如何在一条记录中查询多个对象?