Buried Digits

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

Problem

Only deploys whose environment is stored exactly as the lowercase 'staging' belong in this comparison; the uppercase 'STAGING' rows in deploy_logs came from a retired pipeline and stay out. We want each of those deploys' version as a plain number, so drop the leading 'v' where there is one and the dots between the parts ('v1.0.2' becomes 102), and return it as an integer beside the service name.

The version number is buried in the log.

Tables

deploy_logs

Columns: log_id INTEGER, svc_name TEXT, version TEXT, env_name TEXT, status TEXT, deploy_at TEXT, dur_secs INTEGER, author TEXT

deploy_logs: 10 of 200 rows
log_idsvc_nameversionenv_namestatusdeploy_atdur_secsauthor
131payment-apiv1.0.2stagingfailed2026-02-02 01:11:0023bob
162user-svcv1.1.0devrolled_back2026-03-03 02:22:0036charlie
193search-api2.0.0canaryin_progress2026-04-04 03:33:0049dana
224gatewayv2.1.0ProductionSuccess2026-05-05 04:44:0062eve
255notif-svc2.1.1STAGINGFAILED2026-06-06 05:55:0075frank
286analyticsv3.0.0-rc1productionsuccess2026-07-07 06:06:0088Alice
317ml-servingv1.0.3stagingfailed2026-08-08 07:17:00NULLBOB
348auth-svcv1.0.1devRolled_Back2026-09-09 08:28:00114alice
379Payment-APIv1.0.2canaryin_progress2026-01-10 09:39:00127bob
410user-svcv1.1.0ProductionSuccess2026-02-11 10:50:00140charlie

Expected output

First 5 of 34 rows
svc_nameversion_num
payment-api102
ml-serving103
notif-svc211
search-api200
payment-api102

Worked solution and explanation

What this is really asking

This is a filter-then-normalize problem where the filter is the trap. Turning 'v1.0.2' into 102 takes two REPLACE calls and a CAST, and almost everyone gets there. What separates candidates is the env_name predicate: the column holds both 'staging' and 'STAGING', and only the lowercase rows belong in the comparison. Fold case out of tidiness and the 32 'STAGING' rows ride along. The result grows from 34 rows to 66, and every number in it still looks plausible, so nothing tells you it is wrong.


Break down the requirements

Step 1: Keep only lowercase 'staging'

Compare env_name = 'staging' as it is. Text equality is case-sensitive here, which is exactly what the business rule wants: 'STAGING' came from a retired pipeline and stays out. Any LOWER() or ILIKE lets those rows back in.

Step 2: Strip every non-digit before converting

The staging versions are 'v1.0.2', 'v1.0.3', '2.0.0' and '2.1.1'. One REPLACE removes the 'v' and a second removes the dots. The 'v' pass does nothing on the bare versions, which is fine: it costs nothing and keeps one expression for every row.

Step 3: Cast last

Only once the string is pure digits does CAST(... AS INTEGER) give 102 rather than a truncated 1 or a zero. Name the result version_num so the output reads as the answer.


The solution

The graded query
SELECT svc_name,
       CAST(REPLACE(REPLACE(version, 'v', ''), '.', '') AS INTEGER) AS version_num
FROM deploy_logs
WHERE env_name = 'staging'

Common follow-up questions

Common follow-up questions