Deployed Models by Framework

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
Asked in
Forbes

Problem

Each row in ml_models is one registration of a trained model, and a registration is live only when its status reads exactly 'deployed'. How many live registrations does each model name have?

Which frameworks are actually in production?

Tables

ml_models

Columns: model_id INTEGER, mdl_name TEXT, version TEXT, accuracy REAL, status TEXT, train_at TEXT, framework TEXT

ml_models: 10 of 200 rows
model_idmdl_nameversionaccuracystatustrain_atframework
123rec_enginev1.10.72training2026-02-02 01:00:00TensorFlow
146churn_predv2.00.89archived2026-03-03 02:00:00XGBoost
169spam_filter3.00.61failed2026-04-04 03:00:00sklearn
192img_classifyv2.1-beta0.78validating2026-05-05 04:00:00pytorch
215sentiment1.0.00.95Deployed2026-06-06 05:00:00tensorflow
238demand_fcstv1.00.67deployedNULLPyTorch
261price_optv1.10.84Training2026-08-08 07:00:00TensorFlow
284fraud_detectv2.0NULLarchived2026-09-09 08:00:00XGBoost
307rec_engine3.00.73failed2026-01-10 09:00:00sklearn
330churn_predv2.1-beta0.9validating2026-02-11 10:00:00pytorch

Expected output

First 4 of 4 rows
mdl_namelive_registrations
churn_pred8
demand_fcst8
fraud_detect8
img_classify8

Worked solution and explanation

What this really is

This is a filter wearing an aggregation costume. Anyone can write GROUP BY mdl_name with COUNT(*); the question is whether you throw away the non-live rows first, and whether you throw away the right ones. Skip the filter and every model is padded with its training, archived and failed registrations. Fold the casing with LOWER(status) and the 'Deployed' rows sneak back in. Either way the query runs, and every number on the page is wrong.

Build it in order

Step 1: Filter to live registrations

Keep only rows where status = 'deployed'. This is a condition on each registration, so it belongs in WHERE, which runs before any grouping happens.

Step 2: Count per mdl_name

Group the survivors by mdl_name and count rows with COUNT(*). Each surviving row is one live registration, so the row count is the answer.

Live registrations per model
SELECT mdl_name, COUNT(*) AS live_registrations
FROM ml_models
WHERE status = 'deployed'
GROUP BY mdl_name
Filter in WHERE
WHERE status = 'deployed' removes rows before GROUP BY, so COUNT(*) only ever sees live registrations.
Filter in HAVING
HAVING sees groups, not rows. A row-level test on status there either errors or checks one arbitrary row per group, and the counts still include every status.

Common follow-up questions