Signups by Age Bucket Since April

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
L3
Asked in
Amazon

Problem

Each row of users is one account, stamped with its signup_date and an age_bucket (some accounts have no bucket recorded, and those still form their own group), and the spring signup wave is every account created on or after April 1, 2026. Return each age bucket in that wave alongside its number of signups as user_count, with the buckets in any order.

Recent signups by age.

Tables

users

Columns: user_id INTEGER, username TEXT, email TEXT, signup_date TEXT, account_status TEXT, age_bucket TEXT

users: 10 of 200 rows
user_idusernameemailsignup_dateaccount_statusage_bucket
100alicealice@example.com2025-02-02inactive25-34
197aaron42aaron42@example.com2026-03-03suspended35-44
294 ameliaamelia@example.com2024-04-04pending_verification45-54
391arjun arjun@example.com2025-05-05active55-64
488ava99ava99@example.com2026-06-06inactive65+
585andrew_kandrew_k@example.com2024-07-07suspendedNULL
682anikaanika@example.com2025-08-08 16:34:00pending_verification18-24
779aidenaiden@example.com2026-09-09 14:53:00active25-34
876aria_baria_b@example.com2024-10-10inactive35-44
973brianbrian@example.com2025-11-11suspended45-54

Expected output

First 5 of 7 rows
age_bucketuser_count
NULL4
18-247
25-346
35-445
45-546

Worked solution and explanation

What this really is

This is a filtered headcount dressed up as a demographic profile. Everyone sees that the answer needs one row per age_bucket with a count beside it. What separates candidates is the boundary: 'on or after April 1' is inclusive, and writing signup_date > '2026-04-01' drops the whole April 1 cohort. Nothing errors and the shape looks right, but every bucket comes back short.

Building it

Step 1: Cut the table down to the wave

Filter users with signup_date >= '2026-04-01'. There is no end date, so the wave runs to the latest signup in the table. Filtering before grouping means the engine counts only the rows it will report.

Step 2: Collapse to one row per age_bucket

GROUP BY age_bucket with COUNT(*) gives the signups per bucket. Accounts with no bucket recorded land together in one blank group; the statement says they count, so do not filter them out.

Step 3: Name the count user_count and stop

The result is a breakdown, not a leaderboard: the statement allows any row order, so there is nothing to sort. The alias is part of the shape the grader compares, so call it exactly user_count.

Signups per age bucket since April 1
SELECT age_bucket, COUNT(*) AS user_count
FROM users
WHERE signup_date >= '2026-04-01'
GROUP BY age_bucket

One pass over users: filter, then count per age_bucket.

Leaky boundary
WHERE signup_date > '2026-04-01' skips everyone who joined on April 1. Each bucket is understated by its share of that day.
Inclusive boundary
WHERE signup_date >= '2026-04-01' keeps the first day of the wave, so each bucket's user_count is the full spring cohort.

Common follow-up questions