Batch Job Performance Tiers

A medium SQL interview practice problem on DataDriven. Write the query and run it against a real database, with instant feedback.

Domain
SQL
Difficulty
medium
Seniority
L4
Asked in
Travelport

Problem

The data platform team is grading batch job throughput for their quarterly review, where a job's grade comes from the total rows it processed across all of its runs. A job clearing 700 million rows is 'Outstanding', 350 million up to 700 million is 'Satisfactory', 200 million up to 350 million is 'Unsatisfactory', and anything below 200 million is 'Poor'. Show each job's name, its total rows processed, and its tier.

Every batch job gets a grade.

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 10 rows
job_nametotal_rowsperformance_tier
backup_db74884Poor
cache_warm97000Poor
daily_report71780Poor
data_cleanup66736Poor
email_blast93120Poor

Worked solution and explanation

What this problem really is

Beneath the quarterly-review framing this is a bucketing problem: collapse many job runs down to a per-name total, then map that single aggregate onto ordered tier labels. The trap is treating the CASE as decoration you can skip: the platform's per-name totals actually straddle the 200M/350M/700M cutoffs, so the label IS the answer, not the raw SUM. Two ways candidates blow it: they order the CASE branches low-to-high so the 200-million branch swallows every job, or they group by job_id and report per-run rows instead of per-name throughput. Either way the tiers come out wrong and a top performer gets stamped 'Poor'.


Break down the requirements

Step 1: Pick the grain

batch_jobs carries both job_id and job_name. The prompt grades 'each job's name', so collapse to job_name with GROUP BY job_name. Ask out loud whether the many job_id rows per name are reruns to sum (they are here) or whether you want a max.

Step 2: Aggregate rows

SUM(rows_done) AS total_rows. Sum, not avg, because the tier is about total throughput over the quarter, not per-run average. SUM also skips the null rows_done rows for free, so a crashed run that never logged a count just contributes nothing.

Step 3: Bucket with CASE WHEN

Order branches high-to-low so the first true one wins: >= 700000000 'Outstanding', then >= 350000000, then >= 200000000, else 'Poor'. Wrapping SUM(rows_done) in CASE is fine; the planner computes the aggregate once per group.

Step 4: Sort the output

ORDER BY total_rows DESC so the platform PM reads top throughput first, with job_name as a stable tiebreaker. Don't sort by the tier label; alphabetical 'Outstanding' before 'Poor' is meaningless to a reader.


The solution

TIER BY TOTAL ROWS
SELECT
  job_name,
  SUM(rows_done) AS total_rows,
  CASE
    WHEN SUM(rows_done) >= 700000000 THEN 'Outstanding'
    WHEN SUM(rows_done) >= 350000000 THEN 'Satisfactory'
    WHEN SUM(rows_done) >= 200000000 THEN 'Unsatisfactory'
    ELSE 'Poor'
  END AS performance_tier
FROM batch_jobs
GROUP BY job_name
;

COMMON FOLLOW-UP QUESTIONS

Common follow-up questions