Log Priority

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

Which entries in the server logs that have a recorded response time are urgent for on-call, and which are routine? List each with its server name, original log level and response time in milliseconds, labeled urgent when the level is CRITICAL or ERROR and routine otherwise.

Which servers are on fire before coffee?

Tables

server_logs

Columns: log_id INTEGER, server_name TEXT, log_level TEXT, message TEXT, response_time_ms INTEGER, log_timestamp TEXT

server_logs: 10 of 200 rows
log_idserver_namelog_levelmessageresponse_time_mslog_timestamp
137web-prod-02WARNConnection timeout after 30s232026-02-02 01:07:13
174api-prod-01ERRORDatabase query slow: 2.5sNULL2026-03-03 02:14:26
211api-prod-02DEBUGCache miss for key user_123492026-04-04 03:21:39
248db-primaryCRITICALMemory usage at 85%02026-05-05 04:28:52
285db-replica-01INFOSSL certificate expires in 7 daysNULL2026-06-06 05:35:05
322cache-01WARNRate limit exceeded for IP 192.168.1.x882026-07-07 06:42:18
359worker-01ERRORDisk space low: 10% remaining1012026-08-08 07:49:31
396cdn-edge-usDEBUGNew deployment v2.3.1 startedNULL2026-09-09 08:56:44
433cdn-edge-euCRITICALHealth check passed1272026-01-10 09:03:57
470monitor-01INFOFailed to connect to upstream1402026-02-11 10:10:10

Expected output

First 5 of 134 rows
server_namelog_levelresponse_time_mstriage
web-prod-02WARN23routine
api-prod-02DEBUG49routine
db-primaryCRITICAL0urgent
worker-01ERROR101urgent
monitor-01INFO140routine

Worked solution and explanation

What this really tests

Under the on-call framing this is a two-part row-level transform: give each log a category it doesn't store, and drop the rows you can't act on. Nothing in server_logs carries an urgent/routine flag, so a plain column list can't produce it. You reach for a CASE that tests log_level against the severe levels with IN, and you gate the whole view on response_time_ms IS NOT NULL. Skip that filter and every row with no recorded latency leaks into a view whose entire job is to show what to act on, each one blank where the number should be.


Building the query

Step 1: Drop the rows you can't triage

Keep only rows where response_time_ms IS NOT NULL. A share of the table has no recorded latency, and a triage entry with a blank number is noise, so those rows go before anything else is computed.

Step 2: Derive the triage label

server_logs has no urgent/routine column, so derive it. A CASE that checks log_level IN ('CRITICAL', 'ERROR') returns 'urgent', and the ELSE catches every other level as 'routine'. The IN list keeps the severe set in one place.


The solution

Filtered triage view
SELECT server_name,
       log_level,
       response_time_ms,
       CASE WHEN log_level IN ('CRITICAL', 'ERROR') THEN 'urgent' ELSE 'routine' END AS triage
FROM server_logs
WHERE response_time_ms IS NOT NULL

Common follow-up questions