The First Year

A medium SQL interview practice problem on DataDriven. Write the query and run it against a real database, with instant feedback.

Domain
SQL
Difficulty
medium
Seniority
L4
Asked in
Dropbox

Problem

We want the early adopters who came back, not the ones who signed up and vanished: the users who logged at least two sessions within a year of joining. For each of them, surface the user ID, signup date, and how many sessions landed inside that first-year window, smallest user ID first.

Activated early. A good sign.

Tables

users

Columns: user_id INTEGER, username TEXT, email TEXT, signup_date TEXT, account_status TEXT, age_bucket TEXT

users: 10 of 200 rows
user_idusernameemailsignup_dateaccount_statusage_bucket
100alicealice@example.com2025-02-02inactive25-34
197aaron42aaron42@example.com2026-03-03suspended35-44
294 ameliaamelia@example.com2024-04-04pending_verification45-54
391arjun arjun@example.com2025-05-05active55-64
488ava99ava99@example.com2026-06-06inactive65+
585andrew_kandrew_k@example.com2024-07-07suspendedNULL
682anikaanika@example.com2025-08-08 16:34:00pending_verification18-24
779aidenaiden@example.com2026-09-09 14:53:00active25-34
876aria_baria_b@example.com2024-10-10inactive35-44
973brianbrian@example.com2025-11-11suspended45-54

user_sessions

Columns: session_id INTEGER, user_id INTEGER, device_id INTEGER, session_start TEXT, session_duration_sec INTEGER, pages_viewed INTEGER

user_sessions: 10 of 200 rows
session_iduser_iddevice_idsession_startsession_duration_secpages_viewed
70611972302026-02-02 01:00:00533
71222942592026-03-03 02:00:00766
71833912882026-04-04 03:00:00999
72444883172026-05-05 04:00:0012212
73055853462026-06-06 05:00:0014515
73666823752026-07-07 06:00:0016818
74277794042026-08-08 07:00:0019121
7488876NULL2026-09-09 08:00:0021424
75499734622026-01-10 09:00:0023727
761010704912026-02-11 10:00:0026030

Expected output

First 5 of 13 rows
user_idsignup_datesession_count
1972026-03-033
3912025-05-053
4882026-06-062
6822025-08-08 16:34:004
9732025-11-115

Worked solution and explanation

What this really is

This looks like a plain users-to-sessions join, but the real skill is two filters stacked on a per-user computed interval. Each user's window opens at their own signup and runs 365 days, and then you keep only the users who came back: at least two sessions inside that window. A plain grouped count hands back every user who logged even one qualifying session, which is exactly the one-and-done crowd you are trying to exclude. The threshold on the aggregate is what separates a returning user from a one-time visitor, and it can only be applied after the grouping. Two traps sit underneath: sessions dated before signup produce a negative day difference and sneak in under an upper-bound-only filter, and the INNER JOIN quietly drops session-less accounts, which is what you want. Miss the aggregate threshold and you fill your sticky-early-adopter cohort with people who visited once and never returned.


Break down the requirements

Step 1: Join users to sessions

INNER JOIN users to user_sessions on user_id so only users with sessions are considered. Accounts with no sessions at all fall out here for free.

Step 2: Filter sessions within 365 days of signup

Filter to sessions whose session_start falls between the signup date and 365 days later using julianday() date arithmetic. The lower bound of 0 is what excludes sessions logged before signup.

Step 3: Aggregate per user

GROUP BY user_id and signup_date and COUNT(*) the qualifying sessions per user.

Step 4: Keep only users who came back

Apply HAVING COUNT(*) >= 2 to keep only users who returned. This runs after the grouping, which is why it belongs in HAVING and not WHERE: the per-user count does not exist until aggregation happens.


The solution

Join, window filter, aggregate, then threshold the count
SELECT u.user_id, u.signup_date, COUNT(*) AS session_count
FROM users u
INNER JOIN user_sessions us ON u.user_id = us.user_id
WHERE julianday(us.session_start) - julianday(u.signup_date) BETWEEN 0 AND 365
GROUP BY u.user_id, u.signup_date
HAVING COUNT(*) >= 2
ORDER BY u.user_id

Common follow-up questions