Peak Satisfaction
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
Problem
The employee_metrics table keeps ten different HR metrics in one shared value column, so an analyst building the engagement report can only trust numbers taken from the satisfaction_score readings. She needs the highest and lowest satisfaction score in each fiscal year, along with how many measurements were recorded that year.
Which departments are winning on satisfaction?
Tables
employee_metrics
Columns: metric_id INTEGER, department TEXT, metric_name TEXT, metric_value REAL, fiscal_quarter TEXT, fiscal_year INTEGER
| metric_id | department | metric_name | metric_value | fiscal_quarter | fiscal_year |
|---|---|---|---|---|---|
| 141 | Product | attrition_rate | 7.3 | Q2 | 2025 |
| 182 | Design | avg_tenure_months | 14.6 | Q3 | 2026 |
| 223 | Marketing | satisfaction_score | 21.9 | Q4 | 2024 |
| 264 | Sales | training_hours | 29.2 | Q1 | 2025 |
| 305 | HR | promotions | 36.5 | Q2 | 2026 |
| 346 | Finance | open_positions | 43.8 | Q3 | 2024 |
| 387 | Legal | time_to_hire_days | 51.1 | Q4 | 2025 |
| 428 | Operations | diversity_ratio | 58.4 | Q1 | 2026 |
| 469 | Data | remote_percentage | 65.7 | Q2 | 2024 |
| 510 | Engineering | headcount | 73 | Q3 | 2025 |
Expected output
| fiscal_year | max_score | min_score | measurement_count |
|---|---|---|---|
| 2024 | 78.9 | 21.9 | 8 |
| 2025 | 94.9 | 13.9 | 6 |
| 2026 | 86.9 | 5.9 | 6 |
Worked solution and explanation
What this problem is really testing
Strip off the engagement-report costume and this is a filtered group-wise aggregation: keep one metric's rows, collapse them to one row per fiscal_year, and carry three aggregates at once. Anyone can write MAX(metric_value). What separates candidates is noticing that metric_value is a shared column holding ten unrelated metrics, so WHERE metric_name = 'satisfaction_score' has to run before any grouping. Skip it and every year's peak and floor come from whatever metric runs hottest, and the count balloons tenfold.
Walking to the answer
Step 1: Restrict to satisfaction_score first
employee_metrics is a long, narrow table: the metric's identity lives in metric_name, not in the column name. The filter has to sit in WHERE so the other nine metrics never reach the aggregates.
Step 2: Group by fiscal_year
The report wants a per-year view, so fiscal_year is the grain. One GROUP BY gives one row per year with no extra passes over the table.
Step 3: Emit peak, floor and count together
MAX(metric_value), MIN(metric_value) and COUNT(*) all ride on the same grouping. Writing three subqueries for three numbers is the shape interviewers mark down.
SELECT
fiscal_year,
MAX(metric_value) AS max_score,
MIN(metric_value) AS min_score,
COUNT(*) AS measurement_count
FROM employee_metrics
WHERE metric_name = 'satisfaction_score'
GROUP BY fiscal_yearCommon follow-up questions
- `metric_value` can be `NULL`. How would `MAX`, `MIN` and `COUNT(*)` treat those rows, and when would you switch to `COUNT(metric_value)`? (Tests how aggregates skip NULLs and whether the count should mean rows or recorded scores.)
- HR now wants the same summary for every metric at once. How does the query change? (Probes moving `metric_name` from the filter into the grouping key.)
- How would you add a breakdown by `fiscal_quarter` within each year without scanning the table twice? (Checks comfort with multi-column grouping at a finer grain.)