【问题标题】:.NET SQL Server UDF Windowing [duplicate].NET SQL Server UDF 窗口化 [重复]
【发布时间】:2016-03-30 06:03:48
【问题描述】:

是否可以创建一个可以执行类似于内置窗口函数的功能的 C# SQL Server UDF?

例如,我想编写一个计算移动平均线的函数。我为.NET UDF 找到的唯一文档here 显示了单个值的简单输入。

但是,对于我的 50 天移动平均线,我需要每一行的值,以及前 49 行的值。

【问题讨论】:

  • 为什么不在数据库本身上写一个存储过程呢?
  • @StanShaw 这就是我开始的地方。最终,我将把它扩展到相当多的股票市场数据技术分析计算,我已经读到在 T-SQL 中这样做是一个糟糕的选择,而 .NET UDF 会更好。但是,它没有给出任何上述 UDF 的示例。
  • 您读到存储过程是一个糟糕的选择的原因是什么?
  • 您可以创建一个 SQLCLR 聚合函数。但是,仅支持 partition by 子句。不过,这并不能真正帮助您计算滚动平均值,因为您无需调用 CLR 即可计算平均值。
  • 你使用的是什么版本的 SQL?

标签: c# .net sql-server user-defined-functions sqlclr


【解决方案1】:

如果您使用的是 SQL 2012 或更高版本,则可以将 ROWS PRECEDING 选项与 AVG 一起使用

SELECT 
    AVG([your column]) OVER (
        ORDER BY [your date] 
        ROWS BETWEEN 50 PRECEDING AND CURRENT ROW) AS [Rolling 50 Day Average]
FROM [your table]

至于使用带有窗口的 SQLCLR UDF,它看起来唯一受支持的功能是 PARTITION BY

Is it possible to use user defined aggregates (clr) with window functions (over)?

【讨论】:

  • 我了解在 T-SQL 中做一个简单移动平均线的方法。不过,我想知道它是否可以在 .NET UDF 中复制。
  • 在 SQLCLR 中,它必须采用表值参数。我认为那些只适用于存储过程。
  • 看起来答案是否定的。不在 UDF 中。
  • 为什么不直接说 where [your date] >= dateadd(d, -50, getdate())?有性能差异吗?此外,您的答案是否假设每天不能有超过一条记录 - 如果有超过一条记录,则平均值将不正确,因为它只抓取最后 50 条记录,而不是过去 50 天的价值记录?
  • 这不是一回事。除非您正在执行递归 CTE(如我在顶部的 cmets 中链接的示例中所示...tomaslind.net/2013/10/22/moving-average-in-t-sql
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多