Above Average Interactions

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

Domain
SQL
Difficulty
easy
Seniority
L5
Asked in
Samsara

Problem

A downstream report shows a small set of power users drives most of the platform's session volume. Pull every user whose total session count exceeds the average session count across all users, and lay them out as a leaderboard from the most sessions down to the fewest, breaking any tie in favor of the longer-standing account with the lower user ID.

The average user is boring. Who is above?

Tables

user_sessions

Columns: session_id INTEGER, user_id INTEGER, session_start TEXT, device_id INTEGER, 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 20 rows
user_idtotal_sessions
1008
1975
2945
3915
4885

Worked solution and explanation

Why this problem exists in real interviews

This is a textbook "compare each group to a global aggregate" pattern. It tests whether a candidate can compute a per-user count, then compare each user's count against the average count across all users. The trap is that the threshold is the average of counts, not the count of rows.


Break down the requirements

Step 1: Aggregate sessions to one row per user

GROUP BY user_id with COUNT(*) AS total_sessions gives one row per user with their session count.

Step 2: Compute the average of per-user counts

Wrap the per-user counts in a subquery and take AVG(cnt). This is a single scalar that runs once. Computing AVG(COUNT(*)) directly does not work in standard SQL.

Step 3: Filter to users above that average

HAVING COUNT(*) > (scalar subquery) keeps only users whose count exceeds the average. Use strict > so users sitting exactly at the average are excluded.

Step 4: Rank from most active down

ORDER BY total_sessions DESC puts the heaviest users first, matching the "ranked from most active down" requirement.


The solution

Group, then filter against the average of counts
SELECT user_id, COUNT(*) AS total_sessions
FROM user_sessions
GROUP BY user_id
HAVING COUNT(*) > (
    SELECT AVG(cnt)
    FROM (
        SELECT COUNT(*) AS cnt
        FROM user_sessions
        GROUP BY user_id
    ) sub
)
ORDER BY total_sessions DESC, user_id

Common follow-up questions