Longest Login Streak
For each user, the length of their longest run of consecutive login days.
Start practiceProblem statement
Prompt
Given the logins table below (one row per login, possibly several per user per day), write a query that returns, for each user, the length of their longest run of consecutive login days.
- Output columns:
user_idandlongest_streak, ordered byuser_id. - A user with a single login has a streak of 1.
- Multiple logins on the same day count as one day.
- If two runs are tied for the longest, the length is still reported once.
Example
| user_id | login_at |
|---|---|
| 1 | 2024-01-01 |
| 1 | 2024-01-02 |
| 1 | 2024-01-04 |
| 2 | 2024-01-01 |
Expected result:
| user_id | longest_streak |
|---|---|
| 1 | 2 |
| 2 | 1 |
Constraints
loginshas one row per login; a user can log in several times per day.logins.login_atis aDATEand is notNULL.
Tips
- Same islands technique as "Consecutive Login Days", but finish with
MAX(streak_len)per user. - Dedupe to one row per (user, day) first, or the streak math silently breaks.
Schema
CREATE TABLE logins (
id INTEGER PRIMARY KEY,
user_id INTEGER NOT NULL,
login_at DATE NOT NULL
);
Sample data
INSERT INTO logins (id, user_id, login_at) VALUES
(1, 1, '2024-01-01'),
(2, 1, '2024-01-02'),
(3, 1, '2024-01-03'), -- user 1: 3-day streak
(4, 1, '2024-01-05'),
(5, 2, '2024-01-01'),
(6, 2, '2024-01-02'), -- user 2: 2-day streak
(7, 3, '2024-01-10'); -- user 3: 1 day
Additional hidden fixtures are applied during validation to test edge cases.
Solution
One correct approach — try solving it yourself in the practice editor first, then compare. There is usually more than one valid solution.
-- Reference: longest consecutive-day run per user.
WITH deduped AS (
SELECT DISTINCT user_id, login_at
FROM logins
),
numbered AS (
SELECT user_id, login_at,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_at) AS rn
FROM deduped
),
islands AS (
SELECT user_id,
date(login_at, '-' || rn || ' days') AS grp,
COUNT(*) AS streak_len
FROM numbered
GROUP BY user_id, date(login_at, '-' || rn || ' days')
)
SELECT user_id, MAX(streak_len) AS longest_streak
FROM islands
GROUP BY user_id
ORDER BY user_id;
Key concepts
- Gaps and islands
- ROW_NUMBER
- MAX over groups
- DISTINCT
Related questions
- mediumConsecutive Login DaysFind users who logged in on three or more consecutive calendar days.
- mediumConsecutive NumbersFind numbers that appear three or more times in a row.
- mediumFirst and Last Order Per CustomerShow the date of each customer's first and last order.
- mediumGame Play Analysis IVFind the fraction of players who logged in the day after their first login.
- mediumImmediate Food DeliveryReport the percentage of customers' first orders that were delivered immediately.