Radio Silence

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

Domain
SQL
Difficulty
hard
Seniority
L5

Problem

An engineering manager is auditing which repositories have gone quiet, where a repository's longest silence is the widest stretch of days between two back-to-back commits. Commit timestamps are stored as text and the queries run on SQLite, so the day count has to come out of the stored timestamps. Limit the audit to repositories with a long track record, more than 31 stretches between consecutive commits, and for each surface its longest silence from most silent down, numbering the standings as you go.

Some codebases stop speaking for too long.

Tables

repo_commits

Columns: commit_id INTEGER, repo_name TEXT, author TEXT, message TEXT, added INTEGER, removed INTEGER, commit_at TEXT

repo_commits: 10 of 200 rows
commit_idrepo_nameauthormessageaddedremovedcommit_at
3061backend-apibobAdd unit tests1772026-02-02 01:09:00
3122infracharlieRefactor auth module34142026-03-03 02:18:00
3183ml-pipeline charlieUpdate deps51212026-04-04 03:27:00
3244mobile-appdana Improve perf68282026-05-05 04:36:00
3305data-platformfrank Add caching layer 85352026-06-06 05:45:00
3366frontendAliceFix typo in readme102422026-07-07 06:54:00
3427backend-apiBobNULL119492026-08-08 07:03:00
3488infraaliceWIP136562026-09-09 08:12:00
3549ml-pipelinebob153632026-01-10 09:21:00
3610mobile-appcharlieAdd search endpoint170702026-02-11 10:30:00

Expected output

First 4 of 4 rows
repo_namelongest_silencesilence_rank
infra199.975000000093131
backend-api189.245833333116022
mobile-app187.24583333358173
ml-pipeline183.745833333116024

Worked solution and explanation

What this really is

Strip the audit framing and this is a per-repository maximum of consecutive differences, gated by a track-record filter. Within each repo, line up every commit with the one before it, difference the two timestamps into days, and keep the largest gap. Two tells hide here. First, the average of consecutive gaps quietly telescopes to (last minus first) over the count, so a plain aggregate could fake an average with no ordered offset, but the maximum gap has no such shortcut and forces you to materialize every adjacent difference. Second, the filter counts stretches between commits, not commit rows, and the first commit of each repo opens no stretch.


Why the first commit is not a silence

Count commit rows
COUNT(*) over every commit row gives 34 and 32 for the two history sizes here. Filter > 31 and both clear the bar, so a 32-commit repo with only 31 real stretches leaks into the standings.
Count the stretches
Drop the first-commit NULL gap first, and the counts become 33 and 31. Now > 31 keeps the deep-history repos and drops the thin ones. The undefined first gap is the whole difference between the two.

Break down the requirements

Step 1: Pair each commit with its predecessor

Partition by repo_name and order by commit_at, then LAG(commit_at) hands each row the previous commit's timestamp. The earliest commit in each repo has nothing behind it, so LAG returns NULL there.

Step 2: Turn the pair into a day count

Compute julianday(commit_at) - julianday(previous commit_at). julianday turns a text timestamp into a fractional day count, so the subtraction is already a number of days. The first-commit rows carry a NULL gap; WHERE gap_days IS NOT NULL drops them so they count as neither a stretch nor a silence.

Step 3: Take the max, filter on history, position

Group by repo_name, take MAX(gap_days) as the longest silence, keep only repos with more than 31 surviving stretches via HAVING COUNT(*) > 31, and attach a dense position over those maxima ordered widest first.


The solution

LAG-based gap analysis with a track-record filter
WITH gaps AS (
    SELECT
        repo_name,
        julianday(commit_at) - julianday(LAG(commit_at) OVER (PARTITION BY repo_name ORDER BY commit_at)) AS gap_days
    FROM repo_commits
)
SELECT
    repo_name,
    MAX(gap_days) AS longest_silence,
    DENSE_RANK() OVER (ORDER BY MAX(gap_days) DESC) AS silence_rank
FROM gaps
WHERE gap_days IS NOT NULL
GROUP BY repo_name
HAVING COUNT(*) > 31

Common follow-up questions