The Loudest Machines
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
- ESPN
Problem
An SRE sizing next quarter's log storage wants to see how 2026's load spread across the servers writing to server_logs. Report how many log entries each server wrote that year, busiest first.
Every server keeps a diary. Find the ones that never stop writing.
Tables
server_logs
Columns: log_id INTEGER, server_name TEXT, log_level TEXT, message TEXT, response_time_ms INTEGER, log_timestamp TEXT
| log_id | server_name | log_level | message | response_time_ms | log_timestamp |
|---|---|---|---|---|---|
| 137 | web-prod-02 | WARN | Connection timeout after 30s | 23 | 2026-02-02 01:07:13 |
| 174 | api-prod-01 | ERROR | Database query slow: 2.5s | NULL | 2026-03-03 02:14:26 |
| 211 | api-prod-02 | DEBUG | Cache miss for key user_123 | 49 | 2026-04-04 03:21:39 |
| 248 | db-primary | CRITICAL | Memory usage at 85% | 0 | 2026-05-05 04:28:52 |
| 285 | db-replica-01 | INFO | SSL certificate expires in 7 days | NULL | 2026-06-06 05:35:05 |
| 322 | cache-01 | WARN | Rate limit exceeded for IP 192.168.1.x | 88 | 2026-07-07 06:42:18 |
| 359 | worker-01 | ERROR | Disk space low: 10% remaining | 101 | 2026-08-08 07:49:31 |
| 396 | cdn-edge-us | DEBUG | New deployment v2.3.1 started | NULL | 2026-09-09 08:56:44 |
| 433 | cdn-edge-eu | CRITICAL | Health check passed | 127 | 2026-01-10 09:03:57 |
| 470 | monitor-01 | INFO | Failed to connect to upstream | 140 | 2026-02-11 10:10:10 |
Expected output
| server_name | log_count |
|---|---|
| web-prod-02 | 12 |
| worker-01 | 11 |
| monitor-01 | 11 |
| web-prod-01 | 10 |
| cache-01 | 10 |
Worked solution and explanation
What this really is
Under the capacity-planning story, this is a filtered count per group: carve one calendar year out of a text timestamp, then count every row each server wrote. Everyone writes the GROUP BY. Candidates split on two questions: which rows are in scope, and what gets counted. server_logs spans five years and only part of it falls in 2026, so a count with no year filter inflates every server. About a third of the rows have no response_time_ms, so COUNT(response_time_ms) quietly drops untimed lines that still take up storage.
Step 1: Scope to the year
log_timestamp is text in 'YYYY-MM-DD HH:MM:SS' form. STRFTIME('%Y', log_timestamp) pulls out the four-digit year as text, which you compare against the string '2026'. Comparing the raw column to '2026' matches nothing, because no full timestamp equals a bare year.
Step 2: Count every surviving row
Use GROUP BY server_name with COUNT(*). Every surviving row is one stored line, whatever its log_level and whether or not it was timed, so the row count is the volume. Do not add DISTINCT or a level filter.
Step 3: Busiest first
Sort by log_count descending. Servers tied on volume (two sit at 11, two at 10) may come back in either order. The grader checks that counts never rise down the list. It does not check which tied server is printed first, so no tiebreaker is owed.
SELECT server_name, COUNT(*) AS log_count
FROM server_logs
WHERE STRFTIME('%Y', log_timestamp) = '2026'
GROUP BY server_name
ORDER BY log_count DESCCommon follow-up questions
- The team now wants this broken out by month as well as by server. How does the query change? (Tests adding a derived month column as a second grouping key without breaking the grain.)
- Some servers were decommissioned mid-year and should be dropped entirely. Where would you apply that exclusion, and why there? (Tests filter placement and the difference between filtering rows and filtering groups.)
- How would you return only the top five servers by volume, and what happens if the fifth and sixth are tied? (Tests `LIMIT` after an `ORDER BY` and the need for a tie rule at the cutoff.)