LEAD仅能生成相邻行为边对,无法满足桑基图所需的会话对齐、路径标准化、节点守恒及去重聚合等核心要求。

直接说结论:用 LEAD 构建桑基图所需的数据结构可行,但仅靠它无法生成真正合规的桑基图数据——它只能产出「相邻两步」的边关系,而桑基图要求所有节点流入=流出(守恒律),且路径需按会话对齐、去重、归一化。
为什么 LEAD 是起点,但不是终点
LEAD 的核心作用是把同一用户的连续行为拉成「上一步→下一步」的有序对,这是桑基图最基础的边(flow)来源。但它不处理会话切分、路径截断、节点去重、流量聚合等关键环节,直接拿 LEAD 结果喂给 ECharts 或 FineReport,大概率出现宽度不守恒、节点重复、漏掉长路径等问题。
常见错误现象包括:
- 同一个「首页→搜索」边在不同会话中被重复计数,但未按会话去重,导致 UV 被高估
- 用户路径为「首页→搜索→详情→支付→完成」,
LEAD只产出 4 条边,但桑基图需要把整条路径作为上下文理解分流比例 - 未过滤测试账号、爬虫行为,导致「登录页→404」这类异常边占据过宽流线
必须补上的三步预处理
仅靠 LEAD 输出的原始边,要变成可画桑基图的数据,必须做以下操作:
-
会话对齐:先用
session_id或uid + event_time - interval '30 minutes'划分会话,再对每个会话内行为按时间排序,否则LEAD会跨会话拉边 -
路径截断与标准化:限制最大路径深度(如只取前 5 步),并对每一步 action 做清洗(如统一
'/home'和'/index'为'首页'),避免节点爆炸 -
边聚合与守恒校验:按
(pre_action, aft_action)分组后,用COUNT(DISTINCT session_id)计算边权重;之后必须检查每个节点的SUM(in_flow)是否等于SUM(out_flow),不等说明会话切分或数据缺失
LEAD 的正确写法和典型陷阱
下面这段 SQL 是生产环境常用模板,注意参数和条件的实际含义:
WITH ranked AS (
SELECT
uid,
action,
event_time,
ROW_NUMBER() OVER (PARTITION BY uid, session_id ORDER BY event_time) AS rn
FROM user_event
WHERE event_time >= '2026-09-01'
AND action NOT IN ('heartbeat', 'ping')
),
edges AS (
SELECT
a.action AS pre_action,
LEAD(a.action) OVER (PARTITION BY a.uid, a.session_id ORDER BY a.rn) AS aft_action,
a.session_id
FROM ranked a
)
SELECT
pre_action,
aft_action,
COUNT(DISTINCT session_id) AS flow_value
FROM edges
WHERE pre_action IS NOT NULL
AND aft_action IS NOT NULL
AND pre_action != aft_action
GROUP BY pre_action, aft_action;容易踩的坑:
-
LEAD的OVER子句里漏写session_id,导致跨会话拉边(比如用户 A 下午 5 点退出,第二天早上 9 点再进,LEAD把「退出」连到「首页」) - 没加
action NOT IN (...)过滤心跳事件,结果大量「心跳→心跳」边撑宽了无关流线 - 用
COUNT(*)替代COUNT(DISTINCT session_id),把单个用户多次触发同一条路径当成多个独立路径
后续怎么喂给可视化工具
上面 SQL 输出的是标准桑基图输入格式(source / target / value),但要注意:
- ECharts 的
Sankey组件要求nodes数组必须显式列出所有唯一节点名,不能只靠links推导;所以得额外跑一次SELECT DISTINCT action FROM ...构造 nodes - 如果业务要求区分「新用户首路径」和「老用户回访路径」,不能只靠
uid,得结合注册时间打标,再在edgesCTE 中加WHERE first_session = true - Flow 宽度受最大值影响极大:若某条边是 10000,其余都在 100 以下,小边会细得看不见。建议对
flow_value做对数缩放或分位数截断(如 TOP 95%)
真正难的不是写出 LEAD,而是确保每条边背后对应一个真实、干净、可解释的用户会话单元——这点在十亿级日志里,比语法本身更消耗工程资源。

















