Power Users by Session Activity

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
eBay

Problem

Neither a pile of quick visits nor a couple of marathon sessions makes someone a power user: a power user is an active account in users with at least 3 sessions in user_sessions that average at least 25 pages viewed per session. List each power user's id, username, session count and total pages viewed, most total pages first.

More sessions. More time. The power users.

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 7 rows
user_idusernamesession_counttotal_pages
391arjun 5145
1943cyrus5135
6211jenny_k3135
8151maria3135
1555brooke75125

Worked solution and explanation

What this is really testing

This is a group-level filter dressed up as a marketing case study. Both bars, at least 3 sessions and at least 25 pages per session on average, describe a user's whole history, and neither exists until that user's user_sessions rows collapse into one. Anyone can write the join. What separates candidates is where each filter lives: account_status describes one users row, so it filters before grouping; the count and the average describe the group, so they filter after it. Push the 25-page bar down onto individual sessions and the light sessions quietly vanish: averages inflate, counts shrink, and frequent visitors who really average under 25 slip into the case study.


Build it in order

Step 1: Join users to sessions

JOIN user_sessions us ON u.user_id = us.user_id pairs each user with their sessions. An inner join is right because a user with no sessions can never clear a session bar.

Step 2: Scope to active accounts

WHERE u.account_status = 'active' is a fact about a single users row, so it belongs before grouping. Inactive, suspended and pending accounts never enter a group.

Step 3: Collapse each user's sessions

GROUP BY u.user_id, u.username gives one row per user. COUNT(us.session_id) and SUM(us.pages_viewed) become the reported columns; AVG(us.pages_viewed) is needed only for the bar.

Step 4: Test both bars on the groups, then sort

HAVING COUNT(us.session_id) >= 3 AND AVG(us.pages_viewed) >= 25 tests both bars against the finished groups, then the rows sort by total_pages DESC. The bars catch different people: someone with two heavy sessions clears the average but not the count, and a frequent visitor with light sessions clears the count but not the average.


The solution

Join, scope, group, filter the groups, sort
SELECT
    u.user_id,
    u.username,
    COUNT(us.session_id) AS session_count,
    SUM(us.pages_viewed) AS total_pages
FROM users u
JOIN user_sessions us ON u.user_id = us.user_id
WHERE u.account_status = 'active'
GROUP BY u.user_id, u.username
HAVING COUNT(us.session_id) >= 3 AND AVG(us.pages_viewed) >= 25
ORDER BY total_pages DESC
Filter sessions, then group
WHERE us.pages_viewed >= 25 discards light sessions before grouping. A frequent visitor whose real average is under 25 still clears the count on the sessions left behind, and every surviving session_count and total_pages is understated.
Group, then filter the groups
HAVING AVG(us.pages_viewed) >= 25 averages all of a user's sessions, zero-page visits included. Light visitors are correctly left out, and the reported totals are the real ones.
The seductive wrong version
SELECT
    u.user_id,
    u.username,
    COUNT(us.session_id) AS session_count,
    SUM(us.pages_viewed) AS total_pages
FROM users u
JOIN user_sessions us ON u.user_id = us.user_id
WHERE u.account_status = 'active'
  AND us.pages_viewed >= 25
GROUP BY u.user_id, u.username
HAVING COUNT(us.session_id) >= 3
ORDER BY total_pages DESC

Runs cleanly, returns the wrong users: the 25-page bar is applied per session instead of per user.

Common follow-up questions