Even-ID February Signups
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
- Bosch
Problem
We are auditing an anomaly in the accounts that signed up in February, in any year, and it only touches even-numbered user IDs. Pull those accounts' full profiles from the users table, lowest user ID first.
A very specific slice of a very specific cohort.
Tables
users
Columns: user_id INTEGER, username TEXT, email TEXT, signup_date TEXT, account_status TEXT, age_bucket TEXT
| user_id | username | signup_date | account_status | age_bucket | |
|---|---|---|---|---|---|
| 100 | alice | alice@example.com | 2025-02-02 | inactive | 25-34 |
| 197 | aaron42 | aaron42@example.com | 2026-03-03 | suspended | 35-44 |
| 294 | amelia | amelia@example.com | 2024-04-04 | pending_verification | 45-54 |
| 391 | arjun | arjun@example.com | 2025-05-05 | active | 55-64 |
| 488 | ava99 | ava99@example.com | 2026-06-06 | inactive | 65+ |
| 585 | andrew_k | andrew_k@example.com | 2024-07-07 | suspended | NULL |
| 682 | anika | anika@example.com | 2025-08-08 16:34:00 | pending_verification | 18-24 |
| 779 | aiden | aiden@example.com | 2026-09-09 14:53:00 | active | 25-34 |
| 876 | aria_b | aria_b@example.com | 2024-10-10 | inactive | 35-44 |
| 973 | brian | brian@example.com | 2025-11-11 | suspended | 45-54 |
Expected output
| user_id | username | signup_date | account_status | age_bucket | |
|---|---|---|---|---|---|
| 100 | alice | alice@example.com | 2025-02-02 | inactive | 25-34 |
| 1264 | bilal | bilal@example.com | 2025-02-14 | inactive | NULL |
| 2428 | celine | celine@example.com | 2025-02-26 | inactive | 55-64 |
| 3592 | evelyn | evelyn@example.com | 2025-02-10 | inactive | 35-44 |
| 4756 | gunnar | gunnar@example.com | 2025-02-22 | inactive | 18-24 |
Worked solution and explanation
This is a calendar-month filter on a text column, wearing a data-quality costume. The even IDs are the easy half: user_id is an INTEGER, so user_id % 2 = 0 is the whole story, and dropping it lets the three odd-ID February signups from 2026 back in. February is the half that separates candidates. signup_date is TEXT, so the reflex is to search the string, and a loose search for '-02' also catches the second day of every other month. On this table that adds user 2816 ('2026-03-02') and user 5532 ('2024-10-02'): eleven rows where the review expects nine. The other shortcut, pinning '2025-02', grades right today only because every even-ID February account happens to be from that year.
Building the filter
Step 1: Read the month out of signup_date
The column holds dates as text, and a few rows carry a time of day after the date. strftime('%m', signup_date) parses both shapes and returns the two-digit month as text, so = '02' is February in every year, with no year to hardcode and no day to collide with. Compare to the string '02', not the number 2, because a string is what strftime hands back.
Step 2: Keep only even user_id values
user_id % 2 = 0 is the parity test on an INTEGER key. It trims the twelve February signups to nine: the three from 2026 all have odd IDs.
Step 3: Return the whole profile, lowest ID first
A full profile is every column of users. Name the columns instead of writing SELECT *, so the output does not shift when someone adds one, then ORDER BY user_id for the ascending walk the review reads. user_id is unique, so the order is fully determined.
SELECT user_id, username, email, signup_date, account_status, age_bucket
FROM users
WHERE strftime('%m', signup_date) = '02'
AND user_id % 2 = 0
ORDER BY user_idTwo predicates on one table: the month part of signup_date and the parity of user_id.
- Searching the date text
WHERE signup_date LIKE '%-02%' AND user_id % 2 = 0returns eleven rows: the nine February accounts plus '2026-03-02' and '2024-10-02', because '-02' is also how the second day of a month is written.- Reading the month part
WHERE strftime('%m', signup_date) = '02' AND user_id % 2 = 0looks only at the month position, so the second of March stays a March signup and the result is exactly nine rows.
Common follow-up questions
- How would you let this filter seek instead of scanning all of `users`? (A stored signup month column or an expression index on the month.)
- What if `user_id` were a UUID string? (Parity means nothing on a non-numeric key, so the cohort rule itself has to change.)
- The review now wants each year's February cohort with a count. What changes? (Moving from a filter to grouping on the year part of `signup_date`.)