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

Snowflake中如何计算截至各年月的累计收入除以累计独立用户数

解决累计金额与累计独立账户的平均值计算问题

你的原始SQL仅计算了当月的总金额和独立账户数的比值,要实现从数据起始到对应年月的累计值,需要拆分两步计算:累计总金额、累计独立账户数,再将两者做除法。

方法一:高效分步计算(推荐,适合大数据量)

该方法通过先统计账户首次下单月份,再分别计算累计总金额和累计独立账户数,最后关联结果得到目标值:

WITH 
-- 1. 按月统计当月总金额,并计算累计总金额
monthly_gross AS (
    SELECT
        TO_CHAR(DATE_TRUNC('month', orderdate::date), 'yyyy-mm') AS year_month,
        SUM(grossamount) AS monthly_gross
    FROM orders
    GROUP BY year_month
    ORDER BY year_month
),
cumulative_gross AS (
    SELECT
        year_month,
        SUM(monthly_gross) OVER (ORDER BY year_month) AS total_cumulative_gross
    FROM monthly_gross
),
-- 2. 找出每个账户的首次下单年月
first_order AS (
    SELECT
        accountid,
        TO_CHAR(DATE_TRUNC('month', MIN(orderdate::date)), 'yyyy-mm') AS first_order_month
    FROM orders
    GROUP BY accountid
),
-- 3. 统计到每个年月为止的累计独立账户数
cumulative_accounts AS (
    SELECT
        mg.year_month,
        COUNT(fo.accountid) AS total_cumulative_accounts
    FROM monthly_gross mg
    LEFT JOIN first_order fo ON fo.first_order_month <= mg.year_month
    GROUP BY mg.year_month
    ORDER BY mg.year_month
)
-- 4. 关联累计总金额和累计账户数,计算最终平均值
SELECT
    cg.year_month,
    cg.total_cumulative_gross,
    ca.total_cumulative_accounts,
    cg.total_cumulative_gross::FLOAT / ca.total_cumulative_accounts AS avg_cumulative_gross_per_account
FROM cumulative_gross cg
JOIN cumulative_accounts ca ON cg.year_month = ca.year_month;

方法二:窗口函数快速实现(适合小数据量)

如果你的数据库支持窗口函数中的COUNT(DISTINCT)(如PostgreSQL),可以用更简洁的方式实现:

WITH monthly_data AS (
    SELECT
        TO_CHAR(DATE_TRUNC('month', orderdate::date), 'yyyy-mm') AS year_month,
        SUM(grossamount) AS monthly_total,
        ARRAY_AGG(DISTINCT accountid) AS monthly_accounts
    FROM orders
    GROUP BY year_month
    ORDER BY year_month
)
SELECT
    year_month,
    -- 累计总金额
    SUM(monthly_total) OVER (ORDER BY year_month) AS cumulative_gross,
    -- 累计独立账户数:合并所有历史月份的账户数组后去重计数
    (SELECT COUNT(DISTINCT acct) FROM unnest(ARRAY_AGG(monthly_accounts) OVER (ORDER BY year_month)) AS acct) AS cumulative_unique_accounts,
    -- 计算累计平均值
    SUM(monthly_total) OVER (ORDER BY year_month)::FLOAT / 
    (SELECT COUNT(DISTINCT acct) FROM unnest(ARRAY_AGG(monthly_accounts) OVER (ORDER BY year_month)) AS acct) AS result
FROM monthly_data;

关键说明

  • 累计总金额:通过窗口函数SUM() OVER (ORDER BY year_month)实现按月累加
  • 累计独立账户数:核心是统计所有在当前年月及之前下单过的唯一账户,方法一中通过"首次下单月份"过滤,避免重复计数;方法二中通过合并历史账户数组后去重实现
  • 除法时转换为FLOAT是为了避免整数除法导致结果被截断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 17:07:46