High Volume Batch Jobs

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
Spotify

Problem

A run counts as heavy only when it processed more than 5000 rows. List every heavy run in batch_jobs with its job name, priority and rows processed, most rows first.

Batch jobs that processed millions.

Tables

batch_jobs

Columns: job_id INTEGER, job_name TEXT, status TEXT, rows_done INTEGER, started TEXT, ended TEXT, priority INTEGER, retries INTEGER

batch_jobs: 10 of 200 rows
job_idjob_namestatusrows_donestartedendedpriorityretries
1047user_exportrunning972026-02-02 01:00:002026-02-02 03:11:0030
1094data_cleanupfailed1942026-03-03 02:00:002026-03-03 04:22:0060
1141email_blastqueued2912026-04-04 03:00:002026-04-04 05:33:0090
1188index_rebuildcanceled3882026-05-05 04:00:00NULL20
1235cache_warmCompleted4852026-06-06 05:00:002026-06-06 07:55:0050
1282log_archiveFAILEDNULL2026-07-07 06:00:002026-07-07 08:06:0080
1329metric_aggcompleted6792026-08-08 07:00:002026-08-08 09:17:0010
1376backup_dbrunning7762026-09-09 08:00:00NULL40
1423sync_elasticfailed8732026-01-10 09:00:002026-01-10 11:39:0075
1470daily_reportqueued9702026-02-11 10:00:002026-02-11 12:50:0000

Expected output

First 5 of 82 rows
job_namepriorityrows_done
daily_report09700
daily_report09700
sync_elastic79603
sync_elastic79603
backup_db49506

Worked solution and explanation

This is a row-level filter in reporting clothes, and the trap is in the output, not the query. Once job_id is projected away, separate runs become identical lines: the expected answer opens with 'daily_report', priority 0, 9700 rows, twice. Anyone can write the WHERE. What separates candidates is leaving those twins alone. Reach for DISTINCT or a GROUP BY to tidy them and 82 runs shrink to 41, so every count anyone reads off the list is halved.

Walking it

Step 1: Filter each run on rows_done > 5000

Each row of batch_jobs is one run, and the threshold applies to that run's own count, so it belongs in WHERE. The 32 runs with a NULL rows_done drop out on their own, because a comparison with NULL is never true. That is the right call: a run with no recorded count never showed it cleared the bar.

Step 2: Project three columns and keep every row

Return job_name, priority and rows_done; job_id, status, started, ended and retries stay out. Dropping job_id is what makes two runs look alike. It does not make them one run, and nothing in the ask says to merge them.

Step 3: Sort heaviest first

ORDER BY rows_done DESC carries 'most rows first'. Twins tie on rows_done, and the grader only checks that rows are sorted by it, so no tiebreaker is owed.

Filter and sort, one pass
SELECT job_name, priority, rows_done
FROM batch_jobs
WHERE rows_done > 5000
ORDER BY rows_done DESC
Tidied up
SELECT DISTINCT job_name, priority, rows_done with the same filter returns 41 rows, one per unique line. It looks cleaner and quietly answers 'which unique (name, priority, count) combinations exist'.
Every run
The plain projection returns 82 rows, one per qualifying run, twins included. That is the list of heavy runs that was asked for.

Common follow-up questions