You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用SQL按日计算累计余额的加权平均买入价?

问题排查与修正方案

你的问题核心出在初始CTE的成本计算逻辑错误:转出交易(amount<0)的amount*price被错误计入累计成本总和,导致转出后的累计成本被篡改,进而影响后续买入时的均价计算。

按照需求,转出操作仅减少余额,不改变累计成本(均价沿用前一日),只有买入操作才需更新累计成本和均价。但原脚本里的SUM(amount * price)窗口函数会把转出的负数金额乘价格算入累计成本,完全违背了你的业务逻辑。

修正后的SQL脚本

用递归CTE逐行处理交易,精准跟踪累计余额与累计成本:

WITH RECURSIVE transaction_with_row AS (
    -- 给每个地址的交易按日期排序,生成行号
    SELECT
        block_date,
        address,
        amount,
        price,
        ROW_NUMBER() OVER (PARTITION BY address ORDER BY block_date) AS rn
    FROM your_table_name
),
running_balance AS (
    -- 初始化第一笔交易
    SELECT
        block_date,
        address,
        amount,
        price,
        amount AS cumulative_balance,
        CASE WHEN amount > 0 THEN amount * price ELSE 0 END AS total_cost,
        CASE WHEN amount > 0 THEN price ELSE 0 END AS avg_acq_price
    FROM transaction_with_row
    WHERE rn = 1
    UNION ALL
    -- 递归处理后续交易
    SELECT
        t.block_date,
        t.address,
        t.amount,
        t.price,
        -- 累计余额 = 前一日余额 + 当前交易金额
        rb.cumulative_balance + t.amount,
        -- 累计成本:买入则追加当前成本,转出则沿用前一日成本
        CASE
            WHEN t.amount > 0 THEN rb.total_cost + t.amount * t.price
            ELSE rb.total_cost
        END AS total_cost,
        -- 均价:买入则重新计算,转出则沿用前一日均价
        CASE
            WHEN t.amount > 0 THEN (rb.total_cost + t.amount * t.price) / (rb.cumulative_balance + t.amount)
            ELSE rb.avg_acq_price
        END AS avg_acq_price
    FROM running_balance rb
    JOIN transaction_with_row t ON rb.address = t.address AND rb.rn + 1 = t.rn
)
SELECT
    block_date,
    address,
    amount,
    price,
    cumulative_balance,
    ROUND(avg_acq_price, 3) AS avg_acq_price -- 保留三位小数匹配示例精度
FROM running_balance
ORDER BY address, block_date;

逻辑验证(匹配你的示例)

  • 2023-10-01:累计余额=5,累计成本=5×10=50,均价=50/5=10
  • 2023-10-02:累计余额=5+2=7,累计成本=50+2×12=74,均价=74/7≈10.571
  • 2023-10-03:累计余额=7-3=4,累计成本保留74,均价沿用10.571
  • 2023-10-04:累计余额=4+7=11,累计成本=74+7×30=284,均价=284/11≈25.818(若用近似值10.571计算则为(4×10.571+7×30)/11≈22.935,脚本会用精确值计算,结果更准确)

原脚本错误点总结

  1. SUM(amount * price)窗口函数包含了转出交易的负向成本,导致累计成本被错误减少
  2. 虽然后续用CASE试图修复转出时的均价,但Temp里的avg_acq_price已被污染,后续买入时用错误值计算自然结果偏差

内容的提问来源于stack exchange,提问作者Leo Nguyen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 07:26:37