Deployments per Environment

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
L3
Asked in
ESPN

Problem

Staging has felt overloaded lately: is it really taking more deploys than production? From our deploy_logs, how many deploys has each environment received?

Dev, staging, prod. Where do most deploys land?

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 7 rows
env_namedeploy_count
Dev1
Production34
STAGING32
canary34
dev33

Worked solution and explanation

What this really is

This is a one-pass tally dressed up as an infrastructure complaint, and the only real decision is the grain. Anyone can write the group-and-count. What separates candidates is grouping on the label exactly as `deploy_logs` stores it. The log holds 'staging' and 'STAGING', 'production' and 'Production', and even a lone 'Dev' sitting next to 33 'dev'. Fold the case and you return 4 rows where the answer has 7, and you also bury the fact that something upstream writes inconsistent labels.

Step 1: Read the grain off the preview

The expected output lists 'Dev' with 1 and 'dev' with 33 as separate rows. That settles it: one row per stored env_name value, not one per cleaned-up environment.

Step 2: Count every logged deploy

Staging's load comes from every attempt, not only the ones that worked. COUNT(*) counts every row whatever its status, so failed, rolled back and in-progress deploys all land in the tally.

Step 3: Stop at the GROUP BY

Nothing needs filtering and no order is asked for, so the query ends once each label has its count.

Deploys per stored environment label
SELECT env_name, COUNT(*) AS deploy_count
FROM deploy_logs
GROUP BY env_name
Case-folded
Grouping on LOWER(env_name) returns 4 rows: staging 66, production 66, dev 34, canary 34. It looks tidy, and it is graded wrong.
As stored
Grouping on env_name returns 7 rows, including 'Dev' with 1 and 'STAGING' with 32. That split is the evidence that labels are drifting.

Common follow-up questions