cswork / libraryOpen practice workspace

Coding questions · Meta

Find the most-used app

This question evaluates data manipulation and metrics-definition skills, emphasizing SQL and Python proficiency for aggregating user activity and joining app metadata within analytics workflows.

You work on Oculus app engagement analytics.

Tables

user_activity

  • user_id (BIGINT)
  • date (DATE) — day of activity (assume UTC unless otherwise specified)
  • app_id (INT)
  • session_id (VARCHAR)
  • duration (INT) — session duration in seconds

apps

  • app_id (INT, PK)
  • app_name (VARCHAR)
  • app_category (VARCHAR)

Relationship: user_activity.app_id → apps.app_id.

Task

For the last 7 days (inclusive) relative to a provided :as_of_date, identify the “most used app.”

  1. Write a SQL query that returns the most-used app using one clear definition of “most used” (e.g., number of sessions or total time spent).
  2. In 2–3 sentences, explain the pros/cons of at least two plausible definitions (e.g., sessions vs. total time vs. unique users).

Output

Return exactly one row with at least:

  • app_id
  • app_name
  • your chosen usage metric (e.g., session_cnt or total_duration_seconds)

Assume ties do not need a deterministic tie-breaker unless you choose to add one.

Most-used app in the last 7 days (by total time spent)

You are given two tables:

  • user_activity: one row per app session with its duration
  • apps: app metadata

Define “most used app” as the app with the highest total time spent (sum of duration_minutes) during the last 7 days: FROM 2025-05-26 TO 2025-06-01 (inclusive).

Return the app_id, app_name, and total_duration_minutes for the most-used app. If there is a tie, you may return any of the tied apps.

Table apps

columntypeconstraints
app_idINTPRIMARY KEY
app_nameVARCHAR(100)NOT NULL
app_categoryVARCHAR(50)

Sample data:

app_categoryapp_idapp_name
social101ChatSpace
social102PicShare
game201DragonQuest
game202PuzzlePop
fitness301FitTrack
productivity401TaskPro
video501StreamNow

Table user_activity

columntypeconstraints
session_idVARCHAR(20)PRIMARY KEY
user_idINTNOT NULL
activity_dateDATENOT NULL
app_idINTNOT NULL
duration_minutesINTNOT NULL

Sample data:

activity_dateapp_idduration_minutessession_iduser_id
2025-05-2610130s11
2025-05-2710140s21
2025-05-2820110s31
2025-05-2930120s251
2025-05-3010160s41
2025-06-0110220s51
2025-05-1510130s331
2025-05-2620150s62
2025-05-2720170s72
2025-05-2820230s82
2025-05-2910110s92
2025-05-3099915s242
2025-05-3120190s102
2025-05-0520160s322
2025-05-2610140s113
2025-05-2720140s123
2025-05-2810230s133
2025-05-2920230s143
2025-05-3040115s263
2025-05-2020240s343
2025-05-3010125s154
2025-05-3110235s164
2025-06-015015s274
2025-05-2510215s354
2025-05-26201500s175
2025-05-27201520s185
2025-05-28201510s195
2025-05-29201515s205
2025-05-30201505s215
2025-05-31201530s225
2025-06-01201525s235
2025-05-10201500s285
2025-05-11201510s295
2025-05-12201505s305
2025-05-13201490s315

Expected output

One row: the app with the highest summed duration_minutes from 2025-05-26 through 2025-06-01.

app_idapp_nametotal_duration_minutes
201DragonQuest3865

Hints

  1. Filter to the 7-day window first, then aggregate.
  2. Order by the aggregated total duration and pick the top row.

Time-spent percentage by app category (last 7 days)

Compute the percentage of total time spent (duration_minutes) for each app_category during the last 7 days: FROM 2025-05-26 TO 2025-06-01 (inclusive).

Rules:

  • Join user_activity to apps to get app_category.
  • Some app_id values in user_activity may not exist in apps; treat those as app_category = 'Unknown'.

Return one row per category with:

  • app_category
  • category_duration_minutes
  • pct_of_total_time (percentage from 0 to 100, rounded to 2 decimals).

Table apps

columntypeconstraints
app_idINTPRIMARY KEY
app_nameVARCHAR(100)NOT NULL
app_categoryVARCHAR(50)

Sample data:

app_categoryapp_idapp_name
social101ChatSpace
social102PicShare
game201DragonQuest
game202PuzzlePop
fitness301FitTrack
productivity401TaskPro
video501StreamNow

Table user_activity

columntypeconstraints
session_idVARCHAR(20)PRIMARY KEY
user_idINTNOT NULL
activity_dateDATENOT NULL
app_idINTNOT NULL
duration_minutesINTNOT NULL

Sample data:

activity_dateapp_idduration_minutessession_iduser_id
2025-05-2610130s11
2025-05-2710140s21
2025-05-2820110s31
2025-05-2930120s251
2025-05-3010160s41
2025-06-0110220s51
2025-05-1510130s331
2025-05-2620150s62
2025-05-2720170s72
2025-05-2820230s82
2025-05-2910110s92
2025-05-3099915s242
2025-05-3120190s102
2025-05-0520160s322
2025-05-2610140s113
2025-05-2720140s123
2025-05-2810230s133
2025-05-2920230s143
2025-05-3040115s263
2025-05-2020240s343
2025-05-3010125s154
2025-05-3110235s164
2025-06-015015s274
2025-05-2510215s354
2025-05-26201500s175
2025-05-27201520s185
2025-05-28201510s195
2025-05-29201515s205
2025-05-30201505s215
2025-05-31201530s225
2025-06-01201525s235
2025-05-10201500s285
2025-05-11201510s295
2025-05-12201505s305
2025-05-13201490s315

Expected output

Multiple rows (one per app_category, including 'Unknown'), with total time and percentage of total time for 2025-05-26 through 2025-06-01.

app_categorycategory_duration_minutespct_of_total_time
game392591.92
social2906.79
fitness200.47
Unknown150.35
productivity150.35
video50.12

Hints

  1. Use a LEFT JOIN so activity with missing app metadata is retained.
  2. Compute category totals in a CTE, then use a window SUM to get the overall denominator.

Compare engagement for social-dominant vs game-dominant users (last 7 days)

A PM hypothesizes that people who use social apps are more engaged than people who use game apps.

Use the last 7 days: FROM 2025-05-26 TO 2025-06-01 (inclusive).

Define:

  • Engagement metric per user = (number of sessions in the 7-day window) / 7.
  • User classification based on time spent (duration_minutes) in the 7-day window:
    • 'social_dominant' if social time >= 80% of the user's total time
    • 'game_dominant' if game time >= 80% of the user's total time
    • otherwise 'mixed'
  • Ignore 'Unknown' and other categories for dominance checks, but they still count toward the user's total time.

Return one row per user_group with:

  • user_group
  • user_count
  • avg_sessions_per_day (average of the per-user engagement metric, rounded to 2 decimals).

Table apps

columntypeconstraints
app_idINTPRIMARY KEY
app_nameVARCHAR(100)NOT NULL
app_categoryVARCHAR(50)

Sample data:

app_categoryapp_idapp_name
social101ChatSpace
social102PicShare
game201DragonQuest
game202PuzzlePop
fitness301FitTrack
productivity401TaskPro
video501StreamNow

Table user_activity

columntypeconstraints
session_idVARCHAR(20)PRIMARY KEY
user_idINTNOT NULL
activity_dateDATENOT NULL
app_idINTNOT NULL
duration_minutesINTNOT NULL

Sample data:

activity_dateapp_idduration_minutessession_iduser_id
2025-05-2610130s11
2025-05-2710140s21
2025-05-2820110s31
2025-05-2930120s251
2025-05-3010160s41
2025-06-0110220s51
2025-05-1510130s331
2025-05-2620150s62
2025-05-2720170s72
2025-05-2820230s82
2025-05-2910110s92
2025-05-3099915s242
2025-05-3120190s102
2025-05-0520160s322
2025-05-2610140s113
2025-05-2720140s123
2025-05-2810230s133
2025-05-2920230s143
2025-05-3040115s263
2025-05-2020240s343
2025-05-3010125s154
2025-05-3110235s164
2025-06-015015s274
2025-05-2510215s354
2025-05-26201500s175
2025-05-27201520s185
2025-05-28201510s195
2025-05-29201515s205
2025-05-30201505s215
2025-05-31201530s225
2025-06-01201525s235
2025-05-10201500s285
2025-05-11201510s295
2025-05-12201505s305
2025-05-13201490s315

Expected output

One row per user_group with the number of users in the group and their average sessions-per-day (sessions/7) over 2025-05-26 to 2025-06-01.

avg_sessions_per_dayuser_countuser_group
0.932game_dominant
0.711mixed
0.642social_dominant

Hints

  1. Aggregate to the user level first (total minutes, social minutes, game minutes, sessions).
  2. Classify users with a CASE statement, then aggregate again to compare groups.

How common are unhealthy users (last 30 days)?

Define an 'unhealthy user' as someone who:

  • spent more than 8 hours per day (> 480 minutes) on the platform on a given day, AND
  • had more than 10 such days

Evaluate this in the last 30 days: FROM 2025-05-03 TO 2025-06-01 (inclusive).

Return:

  • unhealthy_user_count
  • total_active_users (users with any activity in the window)
  • unhealthy_user_pct (unhealthy_user_count / total_active_users * 100, rounded to 2 decimals).

Table apps

columntypeconstraints
app_idINTPRIMARY KEY
app_nameVARCHAR(100)NOT NULL
app_categoryVARCHAR(50)

Sample data:

app_categoryapp_idapp_name
social101ChatSpace
social102PicShare
game201DragonQuest
game202PuzzlePop
fitness301FitTrack
productivity401TaskPro
video501StreamNow

Table user_activity

columntypeconstraints
session_idVARCHAR(20)PRIMARY KEY
user_idINTNOT NULL
activity_dateDATENOT NULL
app_idINTNOT NULL
duration_minutesINTNOT NULL

Sample data:

activity_dateapp_idduration_minutessession_iduser_id
2025-05-2610130s11
2025-05-2710140s21
2025-05-2820110s31
2025-05-2930120s251
2025-05-3010160s41
2025-06-0110220s51
2025-05-1510130s331
2025-05-2620150s62
2025-05-2720170s72
2025-05-2820230s82
2025-05-2910110s92
2025-05-3099915s242
2025-05-3120190s102
2025-05-0520160s322
2025-05-2610140s113
2025-05-2720140s123
2025-05-2810230s133
2025-05-2920230s143
2025-05-3040115s263
2025-05-2020240s343
2025-05-3010125s154
2025-05-3110235s164
2025-06-015015s274
2025-05-2510215s354
2025-05-26201500s175
2025-05-27201520s185
2025-05-28201510s195
2025-05-29201515s205
2025-05-30201505s215
2025-05-31201530s225
2025-06-01201525s235
2025-05-10201500s285
2025-05-11201510s295
2025-05-12201505s305
2025-05-13201490s315

Expected output

One row with the count and percentage of unhealthy users among all active users in 2025-05-03 to 2025-06-01.

total_active_usersunhealthy_user_countunhealthy_user_pct
5120

Hints

  1. First roll up to user-day totals, then apply the > 480 minutes rule.
  2. Count qualifying days per user and then count users with days_over_8h > 10.