简体   繁体   English

计算平衡量的窗函数

[英]Window function to calculate On Balance Volume

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

So what I would like to achieve her is... if previous a row bigger/less then current a row then add/substract Volume from previous row c .所以我想实现她的是什么...如果以前的a排大/小于当前a排,然后添加/。减去Volume从上一行c

if a > previous ac = previous c + Volume if a < previous ac = previous c - Volume if a > previous ac = previous c + Volume if a < previous ac = previous c - Volume

But... There is no c row because this is what I am calculating (so row c 's initial value is 0 or NULL) ... there is no pre defined set of data in c .但是...没有c行,因为这是我正在计算的(所以行c的初始值为 0 或 NULL)... c没有预定义的数据集。 One data coming from another... kind of.一个数据来自另一个......有点。

If I would have to write this in another language I would store the value of c in a separate variable like previousRow and would rewrite it with each iteration.如果我必须用另一种语言编写它,我会将c的值存储在一个单独的变量中,例如previousRow并在每次迭代时重写它。

Can I achieve similar thing in TSQL?我可以在 TSQL 中实现类似的功能吗?

Sample Data:样本数据:

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

column c pretty much boils down to a conditional rolling sum, unfortunately, sql server doesn't allow for nesting of window functions, so a derived table to establish the previous a value is necessary.列 c 几乎归结为条件滚动总和,不幸的是,sql server 不允许嵌套窗口函数,因此需要一个派生表来建立前一个 a 值。 After that, sum case when and you should have what you're looking for.在那之后,总结一下什么时候你应该有你正在寻找的东西。

Try this (added additional test values to the set provided above):试试这个(在上面提供的集合中添加了额外的测试值):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM