Forum Discussion

powerbidev123's avatar
powerbidev123
Solution Sage
1 month ago
Solved

SQL help

Return the longest streak of consecutive login days for each user.

  • Hi powerbidev123​ ,

    You can solve this using the gaps-and-islands approach. First remove duplicate login dates, then assign each consecutive sequence to the same group:

    WITH distinct_logins AS (     SELECT DISTINCT         user_id,         CAST(login_date AS date) AS login_date     FROM user_logins ), grouped_logins AS (     SELECT         user_id,         login_date,         DATEADD(             day,             -ROW_NUMBER() OVER (                 PARTITION BY user_id                 ORDER BY login_date             ),             login_date         ) AS streak_group     FROM distinct_logins ), streaks AS (     SELECT         user_id,         MIN(login_date) AS streak_start,         MAX(login_date) AS streak_end,         COUNT(*) AS streak_length     FROM grouped_logins     GROUP BY         user_id,         streak_group ), ranked_streaks AS (     SELECT         *,         ROW_NUMBER() OVER (             PARTITION BY user_id             ORDER BY streak_length DESC, streak_end DESC         ) AS rn     FROM streaks ) SELECT     user_id,     streak_start,     streak_end,     streak_length FROM ranked_streaks WHERE rn = 1 ORDER BY user_id;

     The key idea is that subtracting the row number from each login date produces the same grouping value for consecutive dates.

    DISTINCT is important here in case a user logs in multiple times on the same day.

    You may need to adjust the table and column names to match your schema.

    AI-assisted drafting: AI was used to help structure and phrase this response. I reviewed and validated the technical content before posting.

1 Reply

  • ShivekMaharaj's avatar
    ShivekMaharaj
    Power Participant

    Hi powerbidev123​ ,

    You can solve this using the gaps-and-islands approach. First remove duplicate login dates, then assign each consecutive sequence to the same group:

    WITH distinct_logins AS (     SELECT DISTINCT         user_id,         CAST(login_date AS date) AS login_date     FROM user_logins ), grouped_logins AS (     SELECT         user_id,         login_date,         DATEADD(             day,             -ROW_NUMBER() OVER (                 PARTITION BY user_id                 ORDER BY login_date             ),             login_date         ) AS streak_group     FROM distinct_logins ), streaks AS (     SELECT         user_id,         MIN(login_date) AS streak_start,         MAX(login_date) AS streak_end,         COUNT(*) AS streak_length     FROM grouped_logins     GROUP BY         user_id,         streak_group ), ranked_streaks AS (     SELECT         *,         ROW_NUMBER() OVER (             PARTITION BY user_id             ORDER BY streak_length DESC, streak_end DESC         ) AS rn     FROM streaks ) SELECT     user_id,     streak_start,     streak_end,     streak_length FROM ranked_streaks WHERE rn = 1 ORDER BY user_id;

     The key idea is that subtracting the row number from each login date produces the same grouping value for consecutive dates.

    DISTINCT is important here in case a user logs in multiple times on the same day.

    You may need to adjust the table and column names to match your schema.

    AI-assisted drafting: AI was used to help structure and phrase this response. I reviewed and validated the technical content before posting.