Find Each User's Earliest Seven-Day Activity Streak
ByteDanceData Scientist · Technical ScreenLast updated
Tests your ability to identify consecutive date sequences (gaps-and-islands problem) in PostgreSQL, aggregate streaks, and filter for each user's earliest qualifying period.
Problem Statement
You are given a table named user_activity containing log data of user interactions on a platform. A user may have multiple activity records on the same day.
Write a PostgreSQL query to identify each user's earliest streak of at least 7 consecutive active days. For each qualifying user, return their user_id, the start_date of the streak, and the end_date of that streak.
Rules
- A "streak" consists of consecutive calendar days where the user had at least one activity record on each day.
- If a streak lasts longer than 7 consecutive days, return the actual full streak's start and end dates (not just the first 7 days).
- If a user has multiple qualifying streaks (each >= 7 days), return only the one with the earliest
start_date. - If a user has no streak of at least 7 consecutive days, exclude them from the output.
- Order the final result by
user_idin ascending order.
Schema
CREATE TABLE user_activity (
user_id INT,
active_date DATE
);
Example Input
| user_id | active_date |
|---------|-------------|
| 1 | 2024-01-01 |
| 1 | 2024-01-01 |
| 1 | 2024-01-02 |
| 1 | 2024-01-03 |
| 1 | 2024-01-04 |
| 1 | 2024-01-05 |
| 1 | 2024-01-06 |
| 1 | 2024-01-07 |
| 1 | 2024-01-08 |
| 1 | 2024-02-01 |
| 2 | 2024-01-01 |
| 2 | 2024-01-02 |
| 2 | 2024-01-03 |
| 3 | 2024-03-01 |
| ... (7 consecutive days) ...
Example Output
| user_id | start_date | end_date |
|---------|-------------|-------------|
| 1 | 2024-01-01 | 2024-01-08 |
| 3 | 2024-03-01 | 2024-03-07 |
Explanation
- User 1 has duplicate logs on
2024-01-01, which should be collapsed into a single active day. User 1 maintains a continuous run from2024-01-01to2024-01-08(8 consecutive days >= 7), so the full range2024-01-01to2024-01-08is returned. - User 2 only has 3 consecutive days, so they do not qualify.
- User 3 meets the 7-day threshold and is included.
Hints
Hint 1
Start by deduplicating active dates per user using DISTINCT or GROUP BY so multiple logs on the same date count as one day.
Hint 2
Form island groups by subtracting a ROW_NUMBER() in days from each active_date: consecutive dates will yield the exact same base date.
Hint 3
After aggregating by island group to find each streak's length, start date, and end date, filter for streaks with length >= 7 and use ROW_NUMBER() partitioned by user ordered by start_date to pick the earliest.
Follow-up questions
- How would you adapt your query if weekends (Saturdays and Sundays) should be skipped rather than breaking a streak?
- If the table contains billions of rows, how would you optimize this query in terms of indexing and partitioning?
- How would you change the query if we allowed at most one missing day (a 'grace day') inside a streak without breaking it?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.