Models With Variable Accuracy

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
City and County of San Francisco

Problem

Show each model's lowest and highest accuracy in the ml_models registry, alphabetically by model name. Only the models whose accuracy actually moved between versions belong in the list.

Accuracy should be stable. These models are not.

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 5 of 7 rows
mdl_namemin_accuracymax_accuracy
churn_pred0.550.99
demand_fcst0.670.78
img_classify0.780.9
price_opt0.840.95
rec_engine0.720.84

Worked solution and explanation

This is a group filter dressed up as a registry audit. Whether a model belongs in the answer depends on two numbers that only exist after its versions are collapsed: its lowest and highest accuracy. Anyone can write MIN and MAX per mdl_name. What separates candidates is where the 'they differ' test lives. No single row knows its model's low or high, so the test has to run on the collapsed groups. Skip it and you ship 'fraud_detect', a model with no measured accuracy on any version, as an eighth row with an empty low and high.

Walk it through

Step 1: Collapse versions to one row per mdl_name

ml_models holds one row per version, so 'per model' means GROUP BY mdl_name, not model_id. model_id is unique per row, so grouping by it would give every version its own group where the low always equals the high. MIN(accuracy) and MAX(accuracy) then give each model its range.

Step 2: Test the range after collapsing

The condition compares two aggregates of the same group, so it belongs in HAVING MIN(accuracy) <> MAX(accuracy). A WHERE runs before the groups exist and cannot reference either aggregate, so the engine rejects it outright.

Step 3: Sort by model name

ORDER BY mdl_name. After collapsing, each model name appears once, so the alphabetical order is fully determined with no tiebreaker.

Per-model range, kept only where it moved
SELECT mdl_name, MIN(accuracy) AS min_accuracy, MAX(accuracy) AS max_accuracy
FROM ml_models
GROUP BY mdl_name
HAVING MIN(accuracy) <> MAX(accuracy)
ORDER BY mdl_name
No group filter
GROUP BY mdl_name with MIN and MAX alone returns eight rows. One of them is 'fraud_detect' with both values empty: a model that never moved, reported as if it belongs.
Filter on the range
Adding HAVING MIN(accuracy) <> MAX(accuracy) keeps only groups with a real range, which is seven rows. The same clause would also drop a model whose every version scored identically.

Common follow-up questions