#WriteyourMySQLquerystatementbelowWITHdaily_countsAS(-- Step 1: Filter user dates with exactly one record per day (meeting the requirement of "exactly one action per day")SELECTuser_id,action_date,action,COUNT(*)OVER(PARTITIONBYuser_id,action_date)AScntFROMactivity),filtered_activityAS(-- Step 2: Filter out data with multiple actions on the same daySELECTuser_id,action_date,actionFROMdaily_countsWHEREcnt=1),streak_groupsAS(-- Step 3: Group consecutive dates using the method of subtracting row number from dateSELECTuser_id,action,action_date,DATE_SUB(action_date,INTERVALROW_NUMBER()OVER(PARTITIONBYuser_id,actionORDERBYaction_date)DAY)ASgrpFROMfiltered_activity),streak_summaryAS(-- Step 4: Calculate the length of each consecutive segment and only keep records with length >= 5SELECTuser_id,action,COUNT(*)ASstreak_length,MIN(action_date)ASstart_date,MAX(action_date)ASend_date,-- Sort different streaks for each user to facilitate getting the maximum value laterROW_NUMBER()OVER(PARTITIONBYuser_idORDERBYCOUNT(*)DESC)ASrnkFROMstreak_groupsGROUPBYuser_id,action,grpHAVINGstreak_length>=5)-- Step 5: Extract the longest record for each qualified user and sortSELECTuser_id,action,streak_length,start_date,end_dateFROMstreak_summaryWHERErnk=1ORDERBYstreak_lengthDESC,user_idASC;
importpandasaspddeffind_behaviorally_stable_users(activity:pd.DataFrame)->pd.DataFrame:activity['action_date']=pd.to_datetime(activity['action_date'])# Filter users with only a single action per daydf=activity.assign(cnt=activity.groupby(['user_id','action_date'])['action'].transform('count'))df=df[df['cnt']==1].sort_values(['user_id','action','action_date'])# Identify consecutive intervalsdf['rn']=df.groupby(['user_id','action'])['action_date'].rank(method='first')df['grp']=df['action_date']-pd.to_timedelta(df['rn'],unit='D')# Aggregate streaksstreaks=(df.groupby(['user_id','action','grp']).agg(streak_length=('action_date','count'),start_date=('action_date','min'),end_date=('action_date','max'),).reset_index())# Filter and get the longest streak for each userres=streaks[streaks['streak_length']>=5].sort_values(['streak_length','user_id'],ascending=[False,True])returnres.groupby('user_id').head(1)[['user_id','action','streak_length','start_date','end_date']]