在 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
。
为了计算调整后的成本基础 (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
。