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

如何通过KQL RowCumsum检测计算用户状态切换后的StatusDuration

问题描述

以下是包含两个用户状态数据的表格:

UserIdTstatusStatusDuration(seconds)
12023-03-20T17:09:33.572ZRUNNING0
12023-03-20T17:09:28.572ZRUNNING5
12023-03-20T17:09:23.568ZIdle5
12023-03-20T17:09:18.628Zstop5
12023-03-20T17:09:13.564ZRUNNING5
22023-03-20T17:09:08.56Zoffline0
22023-03-20T17:09:03.764Zoffline5
22023-03-20T17:08:58.556Zoffline10
22023-03-20T17:08:53.596ZRUNNING10
22023-03-20T17:08:48.552ZIdle10

每个UserId内状态首次切换后,剩余记录的时间(T)差值与首次状态切换的时间差一致。需通过KQL的row_cumsum函数计算对应的StatusDuration(seconds)。

解决方案

通过以下KQL代码实现需求,核心逻辑是按用户分组、标记状态切换点、划分状态组后累积计算持续时间:

// 模拟原始数据
let raw_data = datatable(UserId:int, T:datetime, status:string)
[
    1, datetime(2023-03-20T17:09:33.572Z), "RUNNING",
    1, datetime(2023-03-20T17:09:28.572Z), "RUNNING",
    1, datetime(2023-03-20T17:09:23.568Z), "Idle",
    1, datetime(2023-03-20T17:09:18.628Z), "stop",
    1, datetime(2023-03-20T17:09:13.564Z), "RUNNING",
    2, datetime(2023-03-20T17:09:08.56Z), "offline",
    2, datetime(2023-03-20T17:09:03.764Z), "offline",
    2, datetime(2023-03-20T17:08:58.556Z), "offline",
    2, datetime(2023-03-20T17:08:53.596Z), "RUNNING",
    2, datetime(2023-03-20T17:08:48.552Z), "Idle"
];
raw_data
| partition by UserId (
    // 按时间降序排列,确保最新记录在前
    sort by T desc
    // 计算当前记录与下一条记录的时间差(秒)
    | extend time_diff = datetime_diff('second', T, next(T))
    // 标记状态是否发生切换(当前状态与下一条不同则为1,否则0)
    | extend status_switch = iif(status != next(status), 1, 0)
    // 按状态切换点分割分组,同一状态组内的记录共享同一个基准时间差
    | extend group_id = row_cumsum(status_switch, 0)
    // 取每组内的第一个时间差作为基准(首次切换的时间差)
    | summarize base_diff = max(time_diff) by UserId, group_id, status
    // 重新关联原始数据,按组计算累积持续时间
    | join kind=inner raw_data on UserId, status
    | partition by UserId, group_id (
        sort by T desc
        | extend row_num = row_number()
        // 行号减1乘以基准时间差,得到每条记录的持续时间
        | extend StatusDuration = (row_num - 1) * base_diff
    )
    // 整理输出字段
    | project UserId, T, status, StatusDuration
    // 按时间降序排列,还原原始顺序
    | sort by UserId, T desc
)
逻辑说明
  1. 分组排序:用partition by UserId隔离每个用户的数据,同时按时间降序排列,保证最新记录优先处理。
  2. 时间差与切换标记:通过datetime_diff计算相邻记录的时间差,用iif标记状态切换点。
  3. 状态组划分:使用row_cumsum基于切换标记生成分组ID,将连续相同状态的记录归为一组。
  4. 基准时间差提取:每个状态组的首次切换时间差作为该组的基准值,通过summarize提取。
  5. 累积计算持续时间:在每个状态组内生成行号,用行号偏移量乘以基准时间差,得到每条记录的StatusDuration。

内容的提问来源于stack exchange,提问作者Kameshwaran R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 01:22:14