The Full Picture

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
L5
Asked in
DoubleVerify

Problem

The people analytics team is assembling a first-quarter department scorecard, putting each department's total payroll beside the combined Q1 metric value on record for that department. Departments with nothing logged for Q1 still belong on it, reading zero for the metric rather than dropping off.

Two tables know different things about the same people. Combine them.

Tables

employees

Columns: employee_id INTEGER, emp_name TEXT, department TEXT, salary REAL, manager_id INTEGER, hire_date TEXT, user_id INTEGER

employees: 10 of 200 rows
employee_idemp_namedepartmentsalarymanager_idhire_dateuser_id
1Alice ChenEngineering55731NULL2021-02-02100
2Bob MartinezProduct61462NULL2022-03-03197
3Carol WuDesign67193NULL2023-04-04294
4David KimMarketing72924NULL2024-05-05391
5Eve JohnsonSales78655NULL2025-06-06488
6Frank PatelHR84386NULL2026-07-07585
7Grace LeeFinance55117NULL2020-08-08682
8Hank BrownOperations60848NULL2021-09-09779
9Iris DavisData66579NULL2022-10-10876
10Jake WilsonLegal72310NULL2023-11-11973

employee_metrics

Columns: metric_id INTEGER, department TEXT, metric_value REAL, metric_name TEXT, fiscal_quarter TEXT, fiscal_year INTEGER

employee_metrics: 10 of 200 rows
metric_iddepartmentmetric_namemetric_valuefiscal_quarterfiscal_year
141Productattrition_rate7.3Q22025
182Designavg_tenure_months14.6Q32026
223Marketingsatisfaction_score21.9Q42024
264Salestraining_hours29.2Q12025
305HRpromotions36.5Q22026
346Financeopen_positions43.8Q32024
387Legaltime_to_hire_days51.1Q42025
428Operationsdiversity_ratio58.4Q12026
469Dataremote_percentage65.7Q22024
510Engineeringheadcount73Q32025

Expected output

First 5 of 10 rows
departmenttotal_payrollq1_metric_total
Data20794800
Design2021760528.8
Engineering1932520412
Finance2060240252.79999999999998
HR20856200

Worked solution and explanation

What this problem is really about

This is a two-grain problem dressed as a scorecard. Payroll lives on employees, one row per person. The Q1 readings live on employee_metrics, many rows per department. Join the two on department and each of the five departments that logged Q1 comes back as 200 rows: 20 employees times 10 Q1 readings. SUM(e.salary) then counts every salary 10 times, and SUM(m.metric_value) counts every reading 20 times, and the numbers still look plausible. Anyone can write the join. The skill is noticing that each measure has to be totalled at the side that holds it before the two meet.


Building the query

Step 1: Total payroll before the join

SELECT department, SUM(salary) AS total_payroll FROM employees GROUP BY department sits in the FROM as payroll, giving ten rows, one per department. A CTE would read the same; the point is that salary is summed before anything can repeat it.

Step 2: Join the Q1 rows inside the ON

LEFT JOIN employee_metrics m ON m.department = payroll.department AND m.fiscal_quarter = 'Q1'. Each department meets only its own Q1 readings, and the five departments that logged nothing keep one row with an empty match.

Step 3: Sum the readings and zero-fill

Group by payroll.department, payroll.total_payroll so the payroll is carried as a key and never summed again. COALESCE(SUM(m.metric_value), 0) turns an empty match into 0 instead of NULL.


The solution

Payroll first, then a filtered LEFT JOIN
SELECT payroll.department,
       payroll.total_payroll,
       COALESCE(SUM(m.metric_value), 0) AS q1_metric_total
FROM (
    SELECT department, SUM(salary) AS total_payroll
    FROM employees
    GROUP BY department
) payroll
LEFT JOIN employee_metrics m
  ON m.department = payroll.department
 AND m.fiscal_quarter = 'Q1'
GROUP BY payroll.department, payroll.total_payroll
Join, then total
Every employee row meets every Q1 reading of the department. SUM(e.salary) sees each salary 10 times and SUM(m.metric_value) sees each reading 20 times in the five Q1 departments.
Total, then join
payroll has one row per department, so the join attaches at most 10 readings to a single total_payroll. Each measure is summed once, on its own side.
The fan-out that looks right
SELECT e.department,
       SUM(e.salary) AS total_payroll,
       COALESCE(SUM(m.metric_value), 0) AS q1_metric_total
FROM employees e
LEFT JOIN employee_metrics m
  ON m.department = e.department
 AND m.fiscal_quarter = 'Q1'
GROUP BY e.department

Keeps all ten departments, but inflates both totals wherever Q1 was logged.


Common follow-up questions