Find Users with Seven Consecutive Impression Days
AirbnbData Engineer · OnsiteLast updated
Tests your ability to identify consecutive calendar-day activity streaks in PostgreSQL using window functions, date arithmetic, and deduplication.
Problem Statement
At Airbnb, tracking sustained guest and host engagement is crucial for understanding user retention. You are given a table named user_impressions that logs every impression event across listing search results.
Write a PostgreSQL query to find all unique user_ids who have had at least one impression on at least seven consecutive calendar days. If a user has a streak longer than seven days (e.g., 10 consecutive days), they should still be returned, but each qualifying user_id should appear only once in the final output.
Table Schema: user_impressions
| Column Name | Type | Description |
|---|---|---|
impression_id | BIGINT | Unique identifier for each impression event |
user_id | BIGINT | Identifier of the user viewing the listing |
impression_timestamp | TIMESTAMP | Timestamp when the impression occurred (UTC) |
Output Format
Return a single column named user_id sorted in ascending order:
| Column Name | Type |
|---|---|
user_id | BIGINT |
Constraints
- The table may contain multiple impressions for the same user on the same calendar day. These should be treated as a single active day.
- Calendar days are evaluated in UTC based on
impression_timestamp::DATE. - Streaks must be continuous calendar days without gaps.
- 1 <= Number of rows <= 10,000,000
Example
Input
user_impressions:
impression_id | user_id | impression_timestamp
---------------+---------+----------------------
1 | 101 | 2024-03-01 10:15:00
2 | 101 | 2024-03-01 18:30:00
3 | 101 | 2024-03-02 09:00:00
4 | 101 | 2024-03-03 14:22:00
5 | 101 | 2024-03-04 11:05:00
6 | 101 | 2024-03-05 16:45:00
7 | 101 | 2024-03-06 20:10:00
8 | 101 | 2024-03-07 08:00:00
9 | 202 | 2024-03-01 12:00:00
10 | 202 | 2024-03-02 12:00:00
11 | 202 | 2024-03-04 12:00:00
Output
user_id
---------
101
Explanation:
- User
101logged impressions every day from2024-03-01through2024-03-07(7 consecutive days, with duplicate impressions on2024-03-01correctly counted as one day). - User
202was active on March 1, 2, and 4, missing March 3, so their longest streak is only 2 consecutive days.
Hints
Hint 1
Deduplicate the dataset first by extracting distinct pairs of user_id and impression date.
Hint 2
Use either the 'difference between date and row_number()' technique (gaps-and-islands) or a window function like LEAD(..., 6) ordered by date.
Hint 3
Remember to wrap the final query with DISTINCT or GROUP BY to ensure users with streaks longer than 7 days appear only once.
Follow-up questions
- How does the performance of LEAD/LAG compare with the gaps-and-islands (ROW_NUMBER) pattern when scaling to hundreds of millions of rows?
- How would you handle local time zones if each impression recorded a listing or user timezone offset?
- If this query needed to run daily in production, how would you model an incremental aggregate table to avoid scanning the entire historical table?
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.