Daily Error Count Change

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
City and County of San Francisco

Problem

Each row of err_tracks is a single error event stamped with its first_at time, and a day with no errors leaves no rows at all. For every day on record, earliest to latest, show how many errors landed that day, how many landed on the previous day that had any, and how much the count moved.

Errors, trending up or down?

Tables

err_tracks

Columns: err_id INTEGER, err_type TEXT, message TEXT, svc_name TEXT, severity TEXT, count INTEGER, first_at TEXT

err_tracks: 10 of 200 rows
err_iderr_typemessagesvc_nameseveritycountfirst_at
137TypeErrorCannot read property of undefinedpayment-apierror82026-02-02 01:11:00
174ConnectionTimeoutConnection timed out after 30suser-svcwarning152026-03-03 02:22:00
211OutOfMemoryHeap space exhaustedsearch-apiinfo222026-04-04 03:33:00
248FileNotFoundFile /tmp/data.csv not foundgatewayFatal292026-05-05 04:44:00
285PermissionDeniedAccess denied for user rootworkerERROR362026-06-06 05:55:00
322RateLimitExceededToo many requests from 10.0.0.1auth-svcfatal432026-07-07 06:06:00
359ParseErrorMalformed JSON in request bodypayment-apierror502026-08-08 07:17:00
396nullpointerexceptionStack overflow in recursive calluser-svcwarning572026-09-09 08:28:00
433TYPEERRORDivision by zerosearch-apiinfo642026-01-10 09:39:00
470NullPointerExceptionUnexpected null value at line 42gatewayFatalNULL2026-02-11 10:50:00

Expected output

First 5 of 190 rows
error_dateerror_countprev_countday_over_day_change
2026-01-031NULLNULL
2026-01-04110
2026-01-05110
2026-01-06110
2026-01-07110

Worked solution and explanation

The previous day is the previous row

This is a gaps problem dressed up as a trend chart. Rolling err_tracks up to one row per day is the easy half. What separates candidates is what 'the previous day' means when quiet days leave no rows at all. Write it as calendar date minus one, a self-join on error_date - 1, and every day after a gap comes back with a NULL prev_count. On this data that is 01-13, 01-22, 02-01 and dozens more, so the chart shows breaks that are nothing but days without errors.

Build it in two passes

Step 1: Roll up to one row per day

Group err_tracks by DATE(first_at) and count rows with COUNT(*). Each row is one error event. The count column is not a daily total, and 18 of its values are NULL, so SUM(count) answers a different question and silently ignores those events.

Step 2: Reach back to the prior recorded day

Over the daily rows, LAG(error_count) OVER (ORDER BY error_date) returns whichever day precedes this one in the data. Day one has nothing before it, so its prev_count is NULL.

Step 3: Subtract for the change

error_count - prev_count is the movement. NULL minus anything stays NULL, so day one's day_over_day_change is blank without any special case.

Step 4: Project and order

Return error_date, error_count, prev_count and day_over_day_change, ordered by error_date ascending so the chart reads left to right.

The solution

Daily rollup, then `LAG` for the prior recorded day
WITH daily_errors AS (
    SELECT
        DATE(first_at) AS error_date,
        COUNT(*) AS error_count
    FROM err_tracks
    GROUP BY DATE(first_at)
),
with_lag AS (
    SELECT
        error_date,
        error_count,
        LAG(error_count) OVER (ORDER BY error_date) AS prev_count
    FROM daily_errors
)
SELECT
    error_date,
    error_count,
    prev_count,
    error_count - prev_count AS day_over_day_change
FROM with_lag
ORDER BY error_date
Calendar date minus one
A LEFT JOIN of daily_errors to itself on prev.error_date = d.error_date - INTERVAL '1 day' matches only when the literal prior date exists. On 01-13 it looks for 01-12, finds nothing, and returns NULL.
Previous row in date order
LAG(error_count) OVER (ORDER BY error_date) takes the row before, which on 01-13 is 01-10. Every day after the first gets a comparison, which is what the chart needs.

Common follow-up questions