Past the Threshold

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
L3
Asked in
Google

Problem

Our session service is supposed to cap every user at 3 sessions in user_sessions, but the cap was never enforced at write time: which users break it, and how many sessions does each one hold?

Somewhere after the third visit, a habit quietly forms. Find the ones who crossed over.

Tables

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

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

Expected output

First 5 of 20 rows
user_idsession_count
1008
1975
2945
3915
4885

Worked solution and explanation

This is a cardinality-constraint check dressed up as a session cap. The rule says no user may hold more than three sessions, and that rule belongs to a user's whole set of rows, not to any one of them. No row in user_sessions can tell you whether its owner is over the cap, so the count has to exist first and the check has to run on it. Everyone writes the count. What separates candidates is where the check lands and what gets counted. Put it on the rows and the query errors or filters the wrong thing. Count device_id instead of sessions and four violators silently pass. Read 'cap of 3' as 'three is already too many' and the list grows from 20 users to 48.

Getting to the answer

Step 1: Stay inside user_sessions

Everything the check needs, user_id and the sessions themselves, lives in user_sessions. The users table is a temptation: joining it adds a second scan and changes no row of the result, because the session's user_id already identifies the user.

Step 2: Count sessions, not a column

The cap is on sessions, and each row is a session, so COUNT(*) is the measure. COUNT(device_id) counts only non-NULL devices, and 23 sessions have no device recorded. User 876 holds five sessions, three without a device, so the column count reports 2 and hides a real violation.

Step 3: Check the rule once the count exists

The rule is about each user's total, so it goes in HAVING, which runs once per group after COUNT(*) is computed. WHERE runs per session before any grouping and cannot see the count, and most engines reject WHERE COUNT(*) > 3 outright.

Users over the session cap
SELECT user_id, COUNT(*) AS session_count
FROM user_sessions
GROUP BY user_id
HAVING COUNT(*) > 3
Counting rows
COUNT(*): user 876 holds 5 sessions and breaks the cap, and user 100 holds 8. Twenty users are over the cap.
Counting a column
COUNT(device_id): NULL devices are skipped, so 876 drops to 2 and 100 to 6. Four of the twenty violators pass the check without any error.

Common follow-up questions