Top Device by Sessions
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
- Natera
Problem
We're profiling which hardware our audience leans on most so we can prioritize testing for it, with every user session counting toward the type of device it ran on. Return the single busiest device type alongside its session count.
One device type generates the most sessions.
Tables
user_sessions
Columns: session_id INTEGER, user_id INTEGER, device_id INTEGER, session_start TEXT, session_duration_sec INTEGER, pages_viewed INTEGER
| session_id | user_id | device_id | session_start | session_duration_sec | pages_viewed |
|---|---|---|---|---|---|
| 7061 | 197 | 230 | 2026-02-02 01:00:00 | 53 | 3 |
| 7122 | 294 | 259 | 2026-03-03 02:00:00 | 76 | 6 |
| 7183 | 391 | 288 | 2026-04-04 03:00:00 | 99 | 9 |
| 7244 | 488 | 317 | 2026-05-05 04:00:00 | 122 | 12 |
| 7305 | 585 | 346 | 2026-06-06 05:00:00 | 145 | 15 |
| 7366 | 682 | 375 | 2026-07-07 06:00:00 | 168 | 18 |
| 7427 | 779 | 404 | 2026-08-08 07:00:00 | 191 | 21 |
| 7488 | 876 | NULL | 2026-09-09 08:00:00 | 214 | 24 |
| 7549 | 973 | 462 | 2026-01-10 09:00:00 | 237 | 27 |
| 7610 | 1070 | 491 | 2026-02-11 10:00:00 | 260 | 30 |
devices
Columns: device_id INTEGER, device_type TEXT, os_name TEXT, os_version TEXT, browser TEXT
| device_id | device_type | os_name | os_version | browser |
|---|---|---|---|---|
| 201 | desktop | Android | 15.1 | Chrome |
| 230 | tablet | Windows | 16.2 | Firefox |
| 259 | smart_tv | macOS | 17.0 | Edge |
| 288 | wearable | Linux | 11 | Opera |
| 317 | mobile | tvOS | 12 | Samsung Internet |
| 346 | desktop | watchOS | 13 | NULL |
| 375 | tablet | iOS | 10.0.19041 | Safari |
| 404 | smart_tv | Android | 14.1 | Chrome |
| 433 | wearable | Windows | NULL | Firefox |
| 462 | mobile | macOS | 14.0 | Edge |
Expected output
| device_type | session_count |
|---|---|
| smart_tv | 37 |
Worked solution and explanation
What this really is
This is a dimension lookup dressed up as hardware profiling. Session rows carry only a device_id; the label you are asked to count by, device_type, lives on devices, so every session has to be carried over to its type before anything is counted. Everyone writes COUNT(*) and LIMIT 1. What separates candidates is the grain: group by device_id and you crown one physical device with a handful of sessions instead of the busiest category. On this data the lead is a single session (smart_tv 37, desktop and tablet 36), so a sloppy grain or a stray filter flips the winner.
Break down the requirements
Step 1: Carry each session to its device_type
user_sessions holds only device_id; the label lives on devices. INNER JOIN devices d ON us.device_id = d.device_id attaches it. 23 sessions have a NULL device_id, and the inner join drops them because a session with no device has no type. A LEFT JOIN would keep them as a NULL group of 23: it loses here, but it is not a device type, so say why you chose inner.
Step 2: Group on d.device_type, not us.device_id
You want one row per device type (five here), not one per physical device. COUNT(*) counts every session, repeat visits by the same user included; COUNT(DISTINCT us.user_id) would measure reach, which is a different question.
Step 3: Sort and keep the top row
ORDER BY session_count DESC LIMIT 1. Mechanically trivial, semantically loaded: if two types tied for first, LIMIT 1 would keep whichever the engine reads first. Here smart_tv leads by one session, so the cut is clean, but raise the tie question out loud.
The solution
SELECT
d.device_type,
COUNT(*) AS session_count
FROM user_sessions us
INNER JOIN devices d ON us.device_id = d.device_id
GROUP BY d.device_type
ORDER BY session_count DESC
LIMIT 1Common follow-up questions
Common follow-up questions
- Rewrite this to return all device types that tie for first. (Forces `HAVING COUNT(*) = (SELECT MAX(cnt) ...)` or a `DENSE_RANK` filter, and tests whether you know `LIMIT 1` silently breaks ties.)
- What if some `user_sessions.device_id` values are missing or not in `devices`? (Probes orphan handling: switch to `LEFT JOIN` and bucket them as 'unknown', or keep `INNER JOIN` and say what you dropped.)
- Top device type per month. (Adds `DATE_TRUNC('month', session_start)` to the group key, then a `DENSE_RANK() OVER (PARTITION BY month ORDER BY COUNT(*) DESC)` filter.)
- How would you make this fast if `user_sessions` were 30B rows instead of 30M? (Looks for a pre-aggregate: a nightly rollup of `session_count` by `device_type` (or `device_id`) into a small table.)