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

如何利用ROW_NUMBER计算客户最后两笔交易的间隔天数及平均值?

解决客户最后两笔交易间隔天数及平均值计算问题

首先要纠正你现有代码的一个关键问题:按Visit_Date DESC排序时,row_num = 1是客户的最后一笔交易,row_num = 2是倒数第二笔交易,你当前筛选row_num = 2 OR row_num = 3是错误的,应该锁定row_num IN (1,2)的记录。

以下是完整的分步解决方案:


步骤1:获取每个客户的最后两笔交易记录

先修正子查询的筛选条件,拿到每个客户的最近两次交易数据:

SELECT Centre_Id, Cust_Id, Visit_Date, row_num
FROM (
    SELECT Centre_Id, Cust_Id, Visit_Date
        , ROW_NUMBER() OVER (PARTITION BY Cust_Id ORDER BY Visit_Date DESC) AS row_num
    FROM dbo.Fact_Centre_Txn
) AS n
WHERE n.row_num IN (1, 2)

步骤2:计算每个客户的交易间隔天数

这里提供两种简洁的实现方式:

方法一:使用LAG窗口函数(推荐)

直接在子查询中获取倒数第二笔交易的日期,再计算间隔:

WITH CustomerLastTwoTxn AS (
    SELECT 
        Cust_Id,
        Centre_Id,
        Visit_Date,
        -- 获取同一客户的上一笔(倒数第二笔)交易日期
        LAG(Visit_Date) OVER (PARTITION BY Cust_Id ORDER BY Visit_Date DESC) AS Prev_Visit_Date,
        ROW_NUMBER() OVER (PARTITION BY Cust_Id ORDER BY Visit_Date DESC) AS row_num
    FROM dbo.Fact_Centre_Txn
)
SELECT 
    Cust_Id,
    Centre_Id, -- 取最后一笔交易对应的门店ID
    DATEDIFF(day, Prev_Visit_Date, Visit_Date) AS Interval_Days
FROM CustomerLastTwoTxn
WHERE row_num = 1 -- 只保留最后一笔交易的记录
AND Prev_Visit_Date IS NOT NULL -- 过滤只有1笔交易的客户

方法二:使用自连接

通过将同一客户的最后两笔交易自连接,计算日期差:

WITH CustomerLastTwoTxn AS (
    SELECT Centre_Id, Cust_Id, Visit_Date, row_num
    FROM (
        SELECT Centre_Id, Cust_Id, Visit_Date
            , ROW_NUMBER() OVER (PARTITION BY Cust_Id ORDER BY Visit_Date DESC) AS row_num
        FROM dbo.Fact_Centre_Txn
    ) AS n
    WHERE n.row_num IN (1, 2)
)
SELECT 
    t1.Cust_Id,
    t1.Centre_Id, -- 最后一笔交易的门店ID
    DATEDIFF(day, t2.Visit_Date, t1.Visit_Date) AS Interval_Days
FROM CustomerLastTwoTxn t1
JOIN CustomerLastTwoTxn t2 
    ON t1.Cust_Id = t2.Cust_Id 
    AND t1.row_num = 1 
    AND t2.row_num = 2

步骤3:计算所有客户的平均间隔天数

基于步骤2的结果,用AVG函数计算平均值(注意转换为浮点型避免整数取整):

WITH CustomerLastTwoTxn AS (
    SELECT 
        Cust_Id,
        Visit_Date,
        LAG(Visit_Date) OVER (PARTITION BY Cust_Id ORDER BY Visit_Date DESC) AS Prev_Visit_Date
    FROM dbo.Fact_Centre_Txn
),
CustomerInterval AS (
    SELECT 
        DATEDIFF(day, Prev_Visit_Date, Visit_Date) AS Interval_Days
    FROM CustomerLastTwoTxn
    WHERE ROW_NUMBER() OVER (PARTITION BY Cust_Id ORDER BY Visit_Date DESC) = 1
    AND Prev_Visit_Date IS NOT NULL
)
SELECT AVG(CAST(Interval_Days AS FLOAT)) AS Avg_Interval_Days
FROM CustomerInterval

内容的提问来源于stack exchange,提问作者phong nguyễn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 13:07:37