【问题标题】:Window function to calculate On Balance Volume计算平衡量的窗口函数
【发布时间】:2021-12-07 16:38:05
【问题描述】:
select a, b, Volume
case
    when lag(a, 1) over(order by b asc) < a then lag(c, 1) over(order by b asc) + Volume
    when lag(a, 1) over(order by b asc) > a then lag(c, 1) over(order by b asc) - Volume
end as c
from Table

所以我想要实现的是...如果之前的a 行大于/小于当前的a 行,那么从上一行c 中添加/减去Volume

if a &gt; previous a c = previous c + Volume if a &lt; previous a c = previous c - Volume

但是...没有c 行,因为这是我正在计算的(所以行c 的初始值为0 或NULL)...@987654333 中没有预定义的数据集@。一种数据来自另一种……一种。

如果我必须用另一种语言编写它,我会将c 的值存储在一个单独的变量中,例如previousRow,并在每次迭代时重写它。

我可以在 TSQL 中实现类似的事情吗?

样本数据:

a b Volume c
1 2020-01 10 0
2 2020-02 20 20
5 2020-03 40 60
3 2020-04 30 30
1 2020-05 10 20

【问题讨论】:

  • 请提供minimal reproducible example,即样本数据和所需结果(包括边缘情况)以及您的尝试。
  • 我在问题中放了一个示例表。我正在尝试的代码是我已经发布的。这就是我卡住的地方。
  • 可以按B排序(datetimeoffset)
  • @DaleK 给你:investopedia.com/terms/o/onbalancevolume.asp在文章中找到公式
  • 仍然不是有效日期?

标签: sql sql-server tsql window-functions


【解决方案1】:

列 c 几乎可以归结为条件滚动和,不幸的是,sql server 不允许嵌套窗口函数,因此需要一个派生表来建立前一个值。在那之后,总结一下你应该在什么时候找到你想要的东西。

试试这个(在上面提供的集合中添加了额外的测试值):

SELECT
  T.*,
  SUM(
      (
      CASE
      WHEN T.LAG_A IS NULL
        THEN 0
      WHEN T.A > T.LAG_A 
        THEN T.VOLUME 
        ELSE (T.VOLUME*-1) 
      END
    ) 
  ) OVER (ORDER BY T.B ASC) AS C
FROM
  (
  SELECT                 
    MY_TABLE.A,
    LAG(MY_TABLE.A, 1) OVER (ORDER BY MY_TABLE.B ASC) AS LAG_A,
    MY_TABLE.B,
    MY_TABLE.VOLUME
  FROM
    (VALUES (1,CAST('1/1/2021' AS DATE),10),
            (2,CAST('1/2/2021' AS DATE),20),
            (5,CAST('1/3/2021' AS DATE),40),
            (3,CAST('1/4/2021' AS DATE),30),
            (1,CAST('1/5/2021' AS DATE),10),
            (8,CAST('1/6/2021' AS DATE),50),
            (4,CAST('1/7/2021' AS DATE),70)
    ) AS MY_TABLE(A,B,VOLUME)
  ) T

【讨论】:

    猜你喜欢
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    • 1970-01-01
    • 2021-03-01
    • 1970-01-01
    • 2013-03-05
    相关资源
    最近更新 更多