SQL分组问题:按SerialNr分组并在Processstep为Finished处拆分
按SerialNr分组并在Processstep='Finished'处拆分的实现方法
嘿,这个需求我之前帮人解决过好多次,其实用窗口函数(或者pandas的分组累计)就能轻松搞定!核心思路就是给同一个SerialNr下的每一段(从起始到下一个Finished)分配唯一的分组ID,之后用SerialNr+分组ID作为分组依据就行。
SQL实现方案
如果用SQL处理数据,窗口函数是最便捷的工具。你需要先确定一个能排序的字段(比如时间戳、步骤顺序号),保证行的顺序和实际流程一致,然后通过累计计数Finished的出现次数生成分组ID:
SELECT SerialNr, Processstep, -- 关键逻辑:按SerialNr分区,累计Finished的出现次数作为分组ID SUM(CASE WHEN Processstep = 'Finished' THEN 1 ELSE 0 END) OVER ( PARTITION BY SerialNr ORDER BY step_timestamp -- 替换成你的排序字段,比如步骤时间/序号 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS SplitGroupID FROM your_table_name;
简单解释下:
PARTITION BY SerialNr确保只在同一个SerialNr范围内统计ORDER BY step_timestamp保证行的顺序符合实际流程,不然拆分位置会混乱- 每次遇到
Processstep='Finished'就累加1,这样每一段到Finished的行都会有相同的SplitGroupID,下一段会自动生成新的分组ID
之后你就可以用SerialNr和SplitGroupID一起作为分组键,聚合你需要的目标信息。
Python Pandas实现方案
如果用Python处理数据,pandas的分组累计功能也能快速实现需求:
import pandas as pd # 先按SerialNr和排序字段排序,保证流程顺序正确 df = df.sort_values(['SerialNr', 'step_order']) # 给每个SerialNr分组内,累计Finished的出现次数作为分组ID df['SplitGroupID'] = df.groupby('SerialNr')['Processstep'].apply( lambda x: x.eq('Finished').cumsum() ) # 按SerialNr和SplitGroupID分组聚合,这里写你的具体需求 result = df.groupby(['SerialNr', 'SplitGroupID']).agg( latest_step=('Processstep', 'last'), total_duration=('duration', 'sum') )
这种方式和SQL的原理完全一致,都是通过累计分隔点的出现次数拆分分组,逻辑直观容易理解。
不管用哪种工具,核心都是用累计计数标记分隔点,把同一个SerialNr下的连续流程段拆分成独立分组,这个思路几乎适用于所有主流的数据处理工具~
内容的提问来源于stack exchange,提问作者Christoph
相关产品推荐
相关产品推荐

