The Noise Floor

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
mid
Asked in
CrowdStrike

Problem

An on-call lead is combing alert_events for the services that page on genuine emergencies rather than crying wolf, where a real emergency is a critical-severity alert and severity is logged with inconsistent capitalization. For each service, report the share of its alerts that are high or critical, keep only the services where critical alerts are more than 80 percent of that high-or-critical volume, and list the loudest services first.

Not every alert deserves a 3 a.m. page. Find the services where most of them claim they do.

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 4 of 4 rows
svc_nameurgent_pct
gateway69.2
db-primary66.7
auth-svc66.7
user-svc61.5

Worked solution and explanation

What this is really asking

This is a conditional ratio whose denominator is itself a conditional count, dressed up as alert hygiene. Anyone can count criticals per service. What separates candidates is what they divide by: the keep-rule is criticals over the high-or-critical alerts, not over everything. Every service on this data also fires medium and low alerts, so criticals over all alerts never clear 0.692. Divide by COUNT(*) and the 80 percent bar keeps nothing, so the four services whose pages are all critical vanish. Compare severity case-sensitively and half the criticals and highs disappear, so every share you report comes out roughly halved.

The trap lives in the denominator

Criticals over all alerts
SUM(critical) / COUNT(*) peaks at 0.692 on this data ('gateway') because every service also fires medium and low alerts. An 80 percent bar against it returns an empty result, and lowering the bar only measures overall critical volume, not how a service pages.
Criticals over the paging alerts
SUM(critical) / SUM(high or critical) is 1.0 for a service whose pages are all critical and 0.0 for one that only pages on 'high'. That ratio separates the two families, and the 80 percent bar isolates the critical-dominated services.

Building it

Step 1: Normalize case first

severity arrives as 'Critical', 'HIGH', 'critical' and 'high'. Wrap it in LOWER() before every comparison. A case-sensitive match drops half the criticals and highs, which skews both the reported share and the keep-rule.

Step 2: Report the paging share

urgent_pct is the share of all of a service's alerts that page someone: SUM(CASE WHEN LOWER(severity) IN ('critical', 'high') THEN 1 ELSE 0 END) over COUNT(*). Multiplying by 100.0 keeps the division floating point; round to one decimal, as the preview shows.

Step 3: Filter on critical dominance, scoped to the pages

The keep-rule compares two conditional counts in HAVING: criticals over the high-or-critical count must exceed 0.8. The * 1.0 forces decimal division. Without it, engines that divide integers truncate a 79 percent service to 0, and the filter only works by accident.

Step 4: Sort for the on-call reader

ORDER BY urgent_pct DESC puts the loudest services on top. 'auth-svc' and 'db-primary' tie at 66.7, and either order is correct: nothing in the question puts one above the other, so no tiebreaker is owed.

The solution

Critical-dominated services with their paging share
SELECT
  svc_name,
  ROUND(100.0 * SUM(CASE WHEN LOWER(severity) IN ('critical', 'high') THEN 1 ELSE 0 END) / COUNT(*), 1) AS urgent_pct
FROM alert_events
GROUP BY svc_name
HAVING SUM(CASE WHEN LOWER(severity) = 'critical' THEN 1 ELSE 0 END) * 1.0
       / SUM(CASE WHEN LOWER(severity) IN ('critical', 'high') THEN 1 ELSE 0 END) > 0.8
ORDER BY urgent_pct DESC

Common follow-up questions