The Ones That Woke Us

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

Problem

The reliability team is reviewing every serious incident from 2026. Pull the full record of each alert that fired that year at high or critical severity, counting those levels no matter how they were capitalized in the log.

The year's serious incidents, and nothing quieter.

Tables

alert_events

Columns: alert_id INTEGER, svc_name TEXT, severity TEXT, status TEXT, fired_at TEXT, ack_by TEXT, resolved TEXT

alert_events: 10 of 200 rows
alert_idsvc_nameseveritystatusfired_atack_byresolved
129payment-apihighacknowledged2026-02-02 01:07:00bob2026-02-02 03:11:00
158user-svcmediumresolved2026-03-03 02:14:00charlie2026-03-03 04:22:00
187search-apilowsilenced2026-04-04 03:21:00danaNULL
216gatewayCriticalfiring2026-05-05 04:28:00NULL2026-05-05 06:44:00
245notif-svcHIGHacknowledged2026-06-06 05:35:00alice2026-06-06 07:55:00
274db-primarycriticalresolved2026-07-07 06:42:00bobNULL
303cache-01highsilenced2026-08-08 07:49:00charlie2026-08-08 09:17:00
332auth-svcmediumfiring2026-09-09 08:56:00NULL2026-09-09 10:28:00
361payment-apilowacknowledged2026-01-10 09:03:00eveNULL
390user-svcCriticalresolved2026-02-11 10:10:00alice2026-02-11 12:50:00

Expected output

First 5 of 80 rows
alert_idsvc_nameseveritystatusfired_atack_byresolved
129payment-apihighacknowledged2026-02-02 01:07:00bob2026-02-02 03:11:00
216gatewayCriticalfiring2026-05-05 04:28:00NULL2026-05-05 06:44:00
245notif-svcHIGHacknowledged2026-06-06 05:35:00alice2026-06-06 07:55:00
274db-primarycriticalresolved2026-07-07 06:42:00bobNULL
303cache-01highsilenced2026-08-08 07:49:00charlie2026-08-08 09:17:00

Worked solution and explanation

This looks like an incident report but it is really a filtered projection with two quiet traps. The skill being probed: can you match a categorical column that was logged in inconsistent case, and can you pull a calendar year out of a text timestamp? Anyone can write WHERE severity IN ('high', 'critical'). The catch is that the log holds 'HIGH', 'Critical' and 'high' side by side, and string equality is case sensitive, so a bare literal list silently drops every row whose casing does not match. Get that wrong and you hand the reliability team an under-count of the year's incidents while your query still looks correct.

Normalize before you compare

The fix is one function. Fold the column to a single case with LOWER(severity), then compare against a lowercase list. 'HIGH', 'High' and 'high' now collapse to the same token and match. Fold the COLUMN, not your literals: it is the stored data that varies, not your search terms.

Case-folded filter plus year extraction
SELECT *
FROM alert_events
WHERE LOWER(severity) IN ('high', 'critical')
  AND strftime('%Y', fired_at) = '2026';

LOWER() collapses the mixed-case severities; strftime pulls the year straight from the timestamp.

Pulling the year from a timestamp

fired_at is a full timestamp stored as text, so comparing it to a bare year never matches. strftime('%Y', fired_at) reduces it to its four-digit year as a string, which you compare against '2026' (quoted, because the function returns text). EXTRACT(YEAR FROM fired_at) or a closed range from January 1 up to the next January 1 works just as well. What matters is that both ends of the year are bounded.

Naive filter
WHERE severity IN ('high', 'critical') AND fired_at >= '2026-01-01'. This misses every mixed-case severity, and the open-ended date bound would admit rows from any later year.
Robust filter
WHERE LOWER(severity) IN ('high', 'critical') AND strftime('%Y', fired_at) = '2026'. Severity matches regardless of case, and the year comes straight from the timestamp, so adjacent years cannot leak in.

Common follow-up questions