Mobile vs Desktop Session Duration

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
L4
Asked in
ESPN

Problem

For the 2025 mobile-versus-desktop engagement review, the product analytics team wants each user's longest mobile session beside their longest desktop session, built from user_sessions and devices. A session only counts when its device is listed in devices. Everyone with at least one such session gets a row, even users seen only on tablets, TVs or wearables, and a side a user never used stays empty.

Mobile versus desktop. Who stays longer?

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

devices

Columns: device_id INTEGER, device_type TEXT, os_name TEXT, os_version TEXT, browser TEXT

devices: 10 of 200 rows
device_iddevice_typeos_nameos_versionbrowser
201desktopAndroid15.1Chrome
230tabletWindows16.2Firefox
259smart_tvmacOS17.0Edge
288wearableLinux11Opera
317mobiletvOS12Samsung Internet
346desktopwatchOS13NULL
375tabletiOS10.0.19041Safari
404smart_tvAndroid14.1Chrome
433wearableWindowsNULLFirefox
462mobilemacOS14.0Edge

Expected output

First 5 of 19 rows
user_idlongest_mobilelongest_desktop
5144122NULL
5435NULL215
6502432NULL
74721672NULL
84422912NULL

Worked solution and explanation

What this problem really is

This is a two-column pivot dressed up as a device comparison, and the real question is who gets a row. Anyone can write two conditional maximums. What separates candidates is seeing that the link to devices defines the population, not the device type: every user seen on an identified device in 2025 is a row, even one who only ever used a tablet or a TV. Narrow the rows to 'mobile' and 'desktop' and the query returns 8 users instead of 19. The 11 who used neither type vanish when they belong in the answer with both sides empty. Every number you print is right and the row set is still wrong.


Build it in order

Step 1: Restrict to 2025 by session_start

STRFTIME('%Y', s.session_start) = '2025' keeps the calendar year, not a rolling twelve months. The predicate sits on the session side, so it trims rows before they are matched.

Step 2: Inner-join devices on device_id

A NULL device_id equals nothing, and an id with no row in devices has no partner, so both kinds of unidentifiable session drop out here. That is the whole exclusion. Adding a predicate on device_type would be a second, wrong exclusion.

Step 3: Pivot with two conditional maximums per user_id

GROUP BY s.user_id gives one row per user. Each MAX(CASE ...) reads only its own device type, so a phone-only user gets NULL in longest_desktop, and a user whose identified sessions are all 'tablet' or 'wearable' gets NULL in both columns and still keeps the row.

Conditional `MAX` over an inner join
SELECT s.user_id,
    MAX(CASE WHEN d.device_type = 'mobile' THEN s.session_duration_sec END) AS longest_mobile,
    MAX(CASE WHEN d.device_type = 'desktop' THEN s.session_duration_sec END) AS longest_desktop
FROM user_sessions s
JOIN devices d ON s.device_id = d.device_id
WHERE STRFTIME('%Y', s.session_start) = '2025'
GROUP BY s.user_id

One join, one grouping pass, two columns.


The two wrong row sets

Row filter: drops tablet-only users
SELECT s.user_id,
    MAX(CASE WHEN d.device_type = 'mobile' THEN s.session_duration_sec END) AS longest_mobile,
    MAX(CASE WHEN d.device_type = 'desktop' THEN s.session_duration_sec END) AS longest_desktop
FROM user_sessions s
JOIN devices d ON s.device_id = d.device_id
WHERE STRFTIME('%Y', s.session_start) = '2025'
  AND d.device_type IN ('mobile', 'desktop')
GROUP BY s.user_id

Returns 8 rows on the seed; the 11 users seen only on tablets, TVs or wearables disappear.

Left join
LEFT JOIN devices keeps a session whose device_id is NULL or missing from devices, with a NULL device_type. A user who has only those sessions comes out as an empty row that the statement excludes.
Inner join
JOIN devices drops those sessions before grouping. A user appears only with at least one identified device, which is exactly the population the statement defines.

Common follow-up questions