Oracle SQL/Python如何生成连续相同user_id的递增序号列?
Oracle SQL 解决方案
你要实现的是连续相同user_id的序号递增,切换时重置,这不属于RANK()/DENSE_RANK()的适用场景——这类窗口函数是针对全局或固定分组的排名,无法识别连续行的变化。可以通过生成连续分组标识,再结合ROW_NUMBER()实现需求:
SELECT date, code, date_time, user_id, operation, ROW_NUMBER() OVER (PARTITION BY code, grp ORDER BY date_time) AS rank FROM ( SELECT t.*, -- 对比当前行与上一行的user_id,不同则累加1生成连续分组 SUM(CASE WHEN user_id = LAG(user_id) OVER (PARTITION BY code ORDER BY date_time) THEN 0 ELSE 1 END) OVER (PARTITION BY code ORDER BY date_time) AS grp FROM your_table t ) t;
逻辑说明:内层查询用LAG()获取上一行的user_id,通过SUM()生成连续相同user_id的分组grp;外层在code+grp的分组内,用ROW_NUMBER()按date_time生成从1开始的递增序号,实现user_id变化时重置计数。
如果数据已全局按code和date_time排序,可去掉内层和外层的PARTITION BY code,直接全局处理。
Python (Pandas) 解决方案
假设数据已加载到Pandas DataFrame,且已按code和date_time排序,用以下代码实现:
import pandas as pd # 生成连续相同user_id的分组键:user_id与上一行不同时,分组号+1 df['grp'] = df['user_id'].ne(df['user_id'].shift()).cumsum() # 按code和grp分组,生成从1开始的rank列(cumcount默认从0开始,需加1) df['rank'] = df.groupby(['code', 'grp'])['date_time'].cumcount() + 1 # 若不需要临时分组列,可删除 # df.drop('grp', axis=1, inplace=True)
逻辑说明:ne()判断当前行user_id是否与上一行不同,cumsum()累加生成连续分组;cumcount()在每个分组内生成序号,加1后得到符合要求的rank列。
内容的提问来源于stack exchange,提问作者agg0131
相关产品推荐
相关产品推荐

