lead函数仅用于获取用户下一次行为时间,不能直接计算流失间隔;真正计算需用datediff('day', event_time, next_time),且必须配合partition by user_id和严格order by event_time,并对null值做coalesce或case处理。

LEAD 本身不计算“流失间隔”,它只取下一行时间;真正算间隔必须用 DATEDIFF 或日期相减,且要明确定义“流失”——比如最后一次行为后 30 天无动作。
LEAD 必须配合 PARTITION BY user_id 和严格 ORDER BY
Oracle 19c 中 LEAD 不会自动识别用户边界。漏掉 PARTITION BY user_id 会导致跨用户取“下一次”,结果完全错乱。
- 正确写法:
LEAD(event_time) OVER (PARTITION BY user_id ORDER BY event_time) - ORDER BY 字段不能是空值:
event_time为空时会被排在最前,破坏时序;建议提前过滤或用COALESCE(event_time, DATE '1970-01-01') - 同一秒多事件?加二级排序:
ORDER BY event_time, log_id,避免 Oracle 随机取行
Oracle 里算天数差只能用 DATEDIFF('day', ...)
Oracle 不支持直接 next_time - current_time 得整数天(那会返回 INTERVAL DAY TO SECOND 类型),必须用 DATEDIFF 函数显式指定单位。
- 语法:
DATEDIFF('day', current_time, next_time) - 注意顺序:第二个参数是起点,第三个是终点;若
next_time ,结果为负,需用 <code>CASE过滤 - 末次行为的
next_time是 NULL,DATEDIFF会报错,必须先用COALESCE(next_time, SYSDATE)或CASE WHEN next_time IS NOT NULL THEN ... END
“流失间隔”的定义决定你怎么处理 NULL 和默认值
流失不是 LEAD 能推出来的,是你业务规则定的。常见做法是:把“最后一次行为到当前时间”当作潜在流失时长,但不能无条件填充 SYSDATE。
- 如果目标是识别已确认流失(比如 30 天未活跃),就该保留 NULL,再加条件:
WHERE next_time IS NULL AND SYSDATE - event_time >= 30 - 如果目标是估算平均沉默时长,可设兜底值:
COALESCE(DATEDIFF('day', event_time, next_time), 365),但 365 要和你的业务流失阈值一致 - 别用
AVG(...)直接算——NULL 会被忽略,但末次行为样本若占比较高,均值会严重偏高;优先看中位数或分位数
真正容易被忽略的是:LEAD 只暴露数据已有断点,它不解释为什么断。同一个用户,两次间隔 7 天后突然跳到 90 天,LEAD 能给你这个 90,但不会告诉你这是卸载 App、换号,还是单纯忘了登录。得靠后续结合设备 ID、登录 IP、是否还有推送 token 等字段交叉验证,否则所有“流失分析”只是数字游戏。











