如何通过SQL语句统计各SourceName的Status在0和1间的变更次数
结论
这个需求完全可以通过SQL实现。
核心逻辑
状态变更的判定规则是:对同一个SourceName的所有记录,按TimeStamp从早到晚排序后,相邻两条记录的Status值如果出现0和1的跳变(不管是0变1还是1变0),就记为1次变更。只有单条记录、或者相邻记录Status值相同的情况,不计入变更次数。
可直接运行的实现代码
以下写法适配所有支持窗口函数的主流数据库(MySQL 8.0+、PostgreSQL、SQL Server、Oracle等),把代码里的表名替换成你实际的表名即可:
WITH log_with_prev_status AS ( SELECT SourceName, Status, -- 分组取同个数据源按时间排序的上一条状态值 LAG(Status) OVER (PARTITION BY SourceName ORDER BY TimeStamp) AS last_status FROM your_table_name -- 替换为实际业务表名 ) SELECT base.SourceName, -- 统计相邻状态不一致的次数,无变更则返回0 SUM(CASE WHEN t.last_status IS NOT NULL AND t.Status != t.last_status THEN 1 ELSE 0 END) AS Count FROM (SELECT DISTINCT SourceName FROM your_table_name) base LEFT JOIN log_with_prev_status t ON base.SourceName = t.SourceName GROUP BY base.SourceName ORDER BY base.SourceName;
结果验证
用你提供的样例数据执行上述SQL,输出结果和预期完全匹配:
| SourceName | Count |
|---|---|
| Jack | 1 |
| Judy | 2 |
| Mark | 1 |
| Michael | 0 |
如果你使用的是不支持窗口函数的老旧数据库版本(比如MySQL 5.x),可以通过自关联+子查询取每条记录对应上一个时间点的状态值,核心判定逻辑和上述方案完全一致,仅写法上有区别。
内容的提问来源于stack exchange,提问作者Shirley
相关产品推荐
相关产品推荐

