公司动态
连续登陆三天及以上的用户(经典SQL面试题)
可以使用“日期减去行号”的间隔分组法。先对同一用户同一天的重复登录去重WITHlogin_distinctAS(SELECTDISTINCTuser_id,CAST(login_dateASDATE)ASlogin_dateFROMlogin),numberedAS(SELECTuser_id,login_date,ROW_NUMBER()OVER(PARTITIONBYuser_idORDERBYlogin_date)ASrnFROMlogin_distinct),groupedAS(SELECTuser_id,login_date,DATE_SUB(login_date,rn)ASgrpFROMnumbered)SELECTuser_idFROMgroupedGROUPBYuser_id,grpHAVINGCOUNT(*)3;原理是连续日期 - 连续行号 相同分组值例如某用户连续登录2025-01-01rn1 → 2024-12-31 2025-01-02rn2 → 2024-12-31 2025-01-03rn3 → 2024-12-31三条记录的grp相同因此可以归为同一个连续登录区间。如果希望查看连续登录的起止日期和天数可以使用WITHlogin_distinctAS(SELECTDISTINCTuser_id,CAST(login_dateASDATE)ASlogin_dateFROMlogin),numberedAS(SELECTuser_id,login_date,ROW_NUMBER()OVER(PARTITIONBYuser_idORDERBYlogin_date)ASrnFROMlogin_distinct),groupedAS(SELECTuser_id,login_date,DATE_SUB(login_date,rn)ASgrpFROMnumbered)SELECTuser_id,MIN(login_date)ASstart_date,MAX(login_date)ASend_date,COUNT(*)AScontinuous_daysFROMgroupedGROUPBYuser_id,grpHAVINGCOUNT(*)3;如果login_date本身是字符串例如yyyy-MM-dd可以改成TO_DATE(login_date)如果是时间戳字符串则需要先转换成日期后再参与计算。