Between Worlds
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
- L4
- Asked in
- ESPN
Problem
A user who moves between device types, a phone one day and a laptop the next, is what the growth team's cross-device review is chasing, and only sessions tied to a known device in devices say anything about that. From user_sessions, return every such session for those users, with the user ID, OS name, device type and session start.
iOS today, Android tomorrow.
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
| user_id | os_name | device_type | session_start |
|---|---|---|---|
| 100 | iOS | desktop | 2026-03-21 20:00:00 |
| 100 | tvOS | desktop | 2026-07-05 12:00:00 |
| 100 | Android | desktop | 2026-02-17 04:00:00 |
| 100 | Windows | tablet | 2026-06-15 11:00:00 |
| 100 | macOS | smart_tv | 2026-06-15 11:30:00 |
Worked solution and explanation
What they're really testing
This is a unique-value count wearing a cross-device costume. Everyone gets the join and the grouping right; the whole problem turns on what you count per user. COUNT(device_type) counts sessions that have a device, while COUNT(DISTINCT device_type) counts the different kinds of device a user actually touched. Almost every user in this session log stays on one device type for every session, so the session tally clears 'more than one' for nearly everybody and the answer balloons from one user's 6 sessions to 169. The second half is the rejoin: the grouping hands you the qualifying user_ids, but the ask wants every session row back.
Break down the requirements
Step 1: Join user_sessions to devices
Inner-join on device_id to put device_type and os_name on every session. A session with a NULL device_id has no device, so the join drops it, which is exactly what 'tied to a known device' asks for.
Step 2: Find the cross-device users
Group the joined rows by user_id and keep HAVING COUNT(DISTINCT device_type) > 1. The DISTINCT decides the answer here: without it you count sessions, not kinds of device.
Step 3: Bring back every session
Filter the joined rows with WHERE user_id IN (...) and return user_id, os_name, device_type and session_start, one row per session, not one per user.
The solution
SELECT s.user_id, d.os_name, d.device_type, s.session_start
FROM user_sessions s
JOIN devices d ON s.device_id = d.device_id
WHERE s.user_id IN (
SELECT s2.user_id
FROM user_sessions s2
JOIN devices d2 ON s2.device_id = d2.device_id
GROUP BY s2.user_id
HAVING COUNT(DISTINCT d2.device_type) > 1
)- Counting sessions
HAVING COUNT(d2.device_type) > 1is true for any user with two device-linked sessions. Nearly every user qualifies and you return 169 sessions.- Counting device types
HAVING COUNT(DISTINCT d2.device_type) > 1is true only when two sessions ran on different kinds of device. One user qualifies and you return their 6 sessions.
Common follow-up questions
- How would you compute the cross-device flag in a single pass instead of a subquery plus rejoin? (Tests knowing `COUNT(DISTINCT ...)` is not a window aggregate in most engines, while comparing `MIN(device_type)` and `MAX(device_type)` per user is.)
- The review now wants users who used both a 'mobile' and a 'desktop' device specifically. What changes? (Tests moving from a unique count to conditional checks per device type.)
- What index would keep the qualifying-user subquery from scanning all 40,000,000 session rows? (Tests indexing intuition for the dominant join and grouping columns.)