概念说明
LEAD 是Doris的一个分析窗口函数,用于访问当前行之后的行数据,而无需进行自连接。可以获取分区内当前行之后的第N行的值。
语法
LEAD ( <expr> [ , <offset> [ , <default> ] ] )
参数
|---------|------------------|
| 参数 | 说明 |
| expr | 需要获取值的表达式 |
| offset | 向后偏移的行数 |
| default | 当偏移超出窗口范围时返回的默认值 |
返回
返回与输入表达式相同的数据类型。
需求实践
需求分析
在线客服系统中,求每个最后接待客服的三天解决率,指标定义为
分子:同一个访客三天内未重复来访(不限客服),则标记为已解决,否则为未解决;
分母:人工会话数
分析需求可知,要想实现该需求,需要将会话记录按照时间升序排序,计算访客A来访之后的三天内是否有重复来访记录,如果有记录,则上一次会话记录标记为未解决。
访客可以重复来访多次,因此可抽象成访客A的数据按照时间排序,最后一条数据为已解决,之前间隔超过三天的为已解决,否则为未解决。
需求实现
数据来源
ElasticSearch 已经有现成的会话记录表,`session_info_2026-01` ,相关字段数据格式如下:
|-----------|------------------------------|
| 字段 | 含义 |
| sessionId | 会话ID,表的主键 |
| visitorId | 访客ID |
| startTime | 会话开始时间,13位long类型,这里未存为date类型 |
| staffId | 客服ID |
实现步骤
1.连接Doris客户端,创建ElasticSearch的Catalog
CREATE CATALOG es_catalog PROPERTIES (
"type"="es",
"hosts"="http://ip:9200",
"mapping_es_id"="true",
"doc_value_scan" = "true",
"metadata_refresh_interval_sec"="20"
);
- 利用lead 函数构建查询获取同一访客人工会话,每一条数据的对应的下一条数据的会话建立时间。
sql
SELECT
sessionId,
staffId,
visitorId,
startTime,
FROM_UNIXTIME(startTime/1000) startT,
FROM_UNIXTIME(LEAD(startTime,1,NULL) OVER (PARTITION BY visitorId order by startTime)/1000) AS nextStartT
FROM es_catalog.default_db.`session_info_2026-01`
WHERE humanSession=1
查询结果为

- 使用case when 为每一条数据打标记,判断是否已解决;
sql
SELECT
*,
(CASE WHEN nextStartT IS NULL THEN 1
WHEN TIMESTAMPDIFF(HOUR,startT,nextStartT)>72 THEN 1 ELSE 0 END) AS resolved
FROM (
SELECT
sessionId,
staffId,
visitorId,
startTime,
FROM_UNIXTIME(startTime/1000) startT,
FROM_UNIXTIME(LEAD(startTime,1,NULL) OVER (PARTITION BY visitorId order by startTime)/1000) AS nextStartT
FROM es_catalog.default_db.`session_info_2026-01`
WHERE humanSession=1
order by visitorId,startTime
) AS t1
查询结果

- 统计最终结果,求三天解决率
sql
SELECT
staffId `客服ID`,
COUNT(sessionId) `总会话数`,
SUM(resolved) `已解决会话数`,
COUNT(sessionId)-SUM(resolved) AS `未解决会话数`,
ROUND(SUM(resolved)/COUNT(sessionId)*100,2) AS `三天解决率%`
FROM (
SELECT
*,
(CASE WHEN nextStartT IS NULL THEN 1
WHEN TIMESTAMPDIFF(HOUR,startT,nextStartT)>72 THEN 1 ELSE 0 END) AS resolved
FROM (
SELECT
sessionId,
staffId,
visitorId,
startTime,
FROM_UNIXTIME(startTime/1000) startT,
FROM_UNIXTIME(LEAD(startTime,1,NULL) OVER (PARTITION BY visitorId order by startTime)/1000) AS nextStartT
FROM es_catalog.default_db.`session_info_2026-01`
WHERE humanSession=1
order by visitorId,startTime
) AS t1
) AS t2
GROUP BY staffId
ORDER BY `三天解决率%` ASC
查询结果为
