The Roster

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
L5

Problem

Each row of employees is one employee, and user_id links that employee to a platform account when one exists. Count each department's employees that have a linked account, listing the departments with the most linked employees first.

Every department, counted head by head.

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

Expected output

First 5 of 10 rows
departmentlinked_employees
Legal20
Sales18
Product18
Operations18
Marketing18

Worked solution and explanation

What this really tests

This reads like a plain headcount, and that is the disguise. It is really a question about what a count counts. On this table every department has exactly 20 rows, so COUNT(*) hands back ten identical numbers and the 'most first' ordering has nothing to order. The account link lives in user_id, which is empty for a few employees, and only a count over that column sees the gap: 'Legal' keeps all 20 and the other nine departments drop to 18. Count rows instead and you ship ten 20s, nine of them wrong, with 'Legal' sitting wherever the engine happened to leave it.

Building the answer

Step 1: Collapse to one row per department

GROUP BY department gives one output row per department. Apart from the grouping key, the only column in employees that matters is the one recording the account link.

Step 2: Count the column, not the row

COUNT(user_id) skips every row where user_id is NULL, which is exactly the set of employees without a linked account. COUNT(*) would count every employee, linked or not.

Step 3: Sort on the count, largest first

ORDER BY linked_employees DESC puts 'Legal' on top. The other nine tie at 18, and tied rows are accepted in any order, so no second key is owed.

Counting rows
COUNT(*) returns 20 for all ten departments. The ordering decides nothing, and the result claims every employee is linked, which is false for 18 of them.
Counting linked accounts
COUNT(user_id) returns 20 for 'Legal' and 18 for the rest, so 'Legal' leads and the unlinked employees drop out of the count.

The solution

Linked employees per department
SELECT department, COUNT(user_id) AS linked_employees
FROM employees
GROUP BY department
ORDER BY linked_employees DESC

Common follow-up questions