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

SQL窗口函数需Group By却要求Date列参与分组,电商60天留存计算问题

报错原因解释

你遇到的报错本质是SQL执行逻辑和字段可见性的问题:

  • SQL的执行顺序中,GROUP BY 的执行优先级远高于窗口函数和SELECT子句。当你按"Customer ID"分组后,分组结果集里仅保留"Customer ID"这一个可直接访问的字段,其余所有原始表字段都必须被聚合函数包裹才能调用。
  • 你的窗口函数中用到了ORDER BY "Date",但"Date"既不在GROUP BY的分组字段列表里,也没有被任何聚合函数处理,数据库无法识别这个字段,就会抛出你看到的报错。

另外你的写法逻辑也不符合需求:你要的是每个用户的首单后60天的复购情况,但现有窗口函数的逻辑是为每一笔订单计算该订单往后60天的同用户订单数,就算没有报错,也会返回每个用户每笔订单对应一行的结果,不是你要的每个用户仅一行的统计结果。


正确实现方案

你可以分两步计算:先取每个用户的首单日期,再统计首单后60天内的复购次数即可,参考代码如下:

WITH user_first_order AS (
    -- 第一步:计算每个用户的首单日期
    SELECT 
        "Customer ID",
        MIN("Date") AS first_order_date
    FROM "Sales"
    GROUP BY "Customer ID"
)
SELECT 
    u."Customer ID",
    -- 统计首单后60天内的订单数(不含首单本身)
    COUNT(s."Sale ID") AS "60 days Sales",
    -- 直接判断留存状态:有复购则为留存
    CASE WHEN COUNT(s."Sale ID") >= 1 THEN '留存' ELSE '流失' END AS retention_status
FROM user_first_order u
LEFT JOIN "Sales" s
    ON u."Customer ID" = s."Customer ID"
    -- 筛选首单后、首单+60天内的订单
    AND s."Date" > u.first_order_date
    AND s."Date" <= u.first_order_date + INTERVAL '60 days'
GROUP BY u."Customer ID"

如果你的留存规则里需要把首单本身算入购买次数,把s."Date" > u.first_order_date改成s."Date" >= u.first_order_date即可。


内容的提问来源于stack exchange,提问作者Santiago Valdés

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 13:54:05