在 window 函数中如何引用回正在定义的列,即引用自身?

Within a window function how to refer back to the column that is being defined, namely reference to itself?

为了计算调整后的成本基础 (ACB),它是 运行 价格 * 数量 + 佣金的总和,或先前 ACB/Share * 数量的总和,具体取决于是销售还是销售购买。

我有以下 table,名为 transaction_t:

Date Action Quantity Price Commission
2021-01-02 buy 150 110.21 5.95
2021-01-21 buy 360 106.87 5.95
2021-03-21 sell 360 106.87 5.95

为了计算 运行“调整后的成本基础”,我有以下查询:

SELECT 
  SUM(CASE 
        WHEN T.Action in ("buy", "reinvest") THEN T.Quantity
        ​WHEN Action = "sell" THEN -T.Quantity
      END
  ) OVER (ORDER BY T.Date) AS quantity_balance,
  SUM(CASE 
        WHEN T.Action in ("buy", "reinvest") THEN T.Quantity * T.Price + T.Commission
        WHEN T.Action = "sell" THEN T.Quantity * ***(previous_total_acb / previous_quantity_balance)***[1]
      END
  ) OVER (ORDER BY T.Date) AS total_acb
  FROM transaction_t AS T;

此查询无效。因为伪代码 previous_total_acb / previous_quantity_balance 引用了 window 函数中定义的列。

如何在 SQLite 中完成这项工作?

注意[1]:这里的previous_total_acb是一个伪代码,我打算它指的是专栏本身,即total_acb。但是 sqlite 似乎不支持这种循环引用。 previous_quantity_balance 指的是同样由 window 函数创建的兄弟列 quantity_balance。这似乎也不起作用。

您将使用 CTE(或子查询)来准备回溯计算,然后在最终查询中引用它们。 我不明白你的实际 sql。这是一个可能没有意义但只是演示结构的简化版本:

第一个 CTE 只是为了给出一些值,在您的情况下,这些值来自您的 table:

WITH TBL(d, a, q, p)
AS
(
   SELECT * FROM (
              VALUES (20210102, 'buy',  150, 110.21),
                     (20210121, 'buy',  380, 106.87),
                     (20210321, 'sell', 360, 104.33)
                 )
),

所以实际上你会从这里开始 WITH

SRC AS
(
    SELECT d,
           a,
           q,
           p,
           q*p AS cost,
           lag(q*p) OVER (ORDER BY d) AS prev_cost
      FROM TBL
)

产生这个:

+--------+----+---+------+-------+---------+
|d       |a   |q  |p     |cost   |prev_cost|
+--------+----+---+------+-------+---------+
|20210102|buy |150|110.21|16531.5|NULL     |
|20210121|buy |380|106.87|40610.6|16531.5  |
|20210321|sell|360|104.33|37558.8|40610.6  |
+--------+----+---+------+-------+---------+

然后您可以使用当前值和先前值生成计算字段

SELECT d, cost, cost-prev_cost AS diff FROM SRC ORDER BY d;

其中(正如我所说的只是为了演示,在这里没有实际意义)产生

+--------+-------+----------+
|d       |cost   |diff      |
+--------+-------+----------+
|20210102|16531.5|NULL      |
|20210121|40610.6|24079.1   |
|20210321|37558.8|-3051.79  |
+--------+-------+----------+

因此将它们放在一起并假设您的数据存储在 TBL 中,它看起来像

WITH SRC AS
(
    SELECT d,
           a,
           q,
           p,
           q*p AS cost,
           lag(q*p) OVER (ORDER BY d) AS prev_cost
      FROM TBL
)
SELECT d, cost, cost-prev_cost AS diff FROM SRC ORDER BY d;

您可以根据需要使用尽可能多的 CTE 来准备您的 'lookback' 数据。不确定,但在您可以在最终查询中使用它之前,您的情况似乎至少需要一个中间准备 CTE 来计算 previous_total_acb