The Apprentices Still in the Forge

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
Google

Problem

The ML platform team is sizing a new training GPU cluster and needs to know how much of the catalog is still mid-flight, meaning models whose status is 'training'. Count the unique model names (mdl_name) in that state and return it as training_count.

A model is not a model until it stops learning and starts earning.

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 1 of 1 rows
training_count
4

Worked solution and explanation

The real problem beneath the costume

Two things are hiding in plain sight. A single model ships as many rows, one per version, so counting rows counts releases, not models. And the status column was never normalized on write, so 'training', 'Training', and 'TRAINING' all live side by side. Match the raw string and you silently drop part of the fleet; count rows and you inflate a small backlog into a large one. Both mistakes send the wrong number to the people buying GPUs.


How to get there

Step 1: Normalize the filter first

LOWER(status) = 'training' folds every casing of the status into one match, so 'Training' and 'TRAINING' rows are not lost. Do this before you count, or the count is already wrong.

Step 2: Count models, not rows

COUNT(DISTINCT mdl_name) collapses the version rows down to one per model name. COUNT(*) here would answer a different question: how many training version rows exist, not how many models are training.


The solution

Filtered distinct count
SELECT COUNT(DISTINCT mdl_name) AS training_count
FROM ml_models
WHERE LOWER(status) = 'training'
COUNT(*) (wrong)
If rec_engine has three versions in training, this returns 3 for that one model. You end up sizing the cluster for phantom models.
COUNT(DISTINCT `mdl_name`) (right)
The same three rows collapse to 1. You count the model once, which is what capacity planning actually needs.

Common follow-up questions