Skip to content
Datasets / Employee Directory
Dataset

Employee Directory SQL Practice Dataset

Departments, employees, projects, and assignments, with a reporting line for self-join practice.

Tables
4
Rows
57
Size
Small
Level
Intermediate
Domain
HR
Formats
CSV · SQL

Download this dataset, free

No account, no email, no attribution required: dedicated to the public domain under CC0 1.0, so commercial use and redistribution are fine. Open it in the browser playground, take the single employee_directory.sql file to load every table into PostgreSQL, MySQL, SQLite, DuckDB, or SQL Server, or grab the raw CSV files below.

employee_directory.sql All 4 tables, 57 rows, as CREATE TABLE and INSERT statements. Download →

Employee Directory is the classic company schema: five departments, eighteen employees, eight projects, and the assignments that put people on them. It is the dataset most SQL exercises and interview questions assume, so it is the fastest way to practice the patterns those questions test.

The column that makes it worth practicing on is employees.manager_id. It points back at employee_id in the same table, so listing someone next to their manager means joining employees to itself. The reporting line runs five levels deep, from the CEO down to a junior engineer, and the CEO sits at the top with no manager and no department, which is exactly where an inner join quietly drops a row and a left join keeps it.

Employees and projects meet many-to-many through assignments, so summing hours per project means joining three tables and grouping the result. One employee has no assignments at all, and running projects have a null end_date, which gives you honest cases for IS NULL, NOT EXISTS, and left joins that are supposed to return nulls.

Salaries are whole-dollar integers across a realistic spread, so averages, medians, and per-department comparisons all produce numbers you can sanity check by eye against eighteen rows.

Schema

How the Employee Directory tables join departmentsemployeesprojectsassignments department_idemployee_iddepartment_idmanager_idproject_iddepartment_idassignment_idemployee_idproject_id PKPKFKFKPKFKPKFKFK + 3 more columns+ 5 more columns+ 4 more columns+ 2 more columns
Arrows point from a column to the key it references. PK marks a table's key and FK a column that references another table.
Join conditions
  • employees.department_id = departments.department_id
  • employees.manager_id = employees.employee_id
  • projects.department_id = departments.department_id
  • assignments.employee_id = employees.employee_id
  • assignments.project_id = projects.project_id
Schema · Employee Directory View dataset schema 4 tables
Table · departments

One row per department.

4 columns · 5 rows
department_id int department_name text location text annual_budget int
Table · employees

One row per employee. manager_id points back at employee_id in this same table, and the CEO has neither a manager nor a department.

8 columns · 18 rows
employee_id int first_name text last_name text job_title text department_id int manager_id int hire_date date salary int
Table · projects

One row per project. Projects still running have a null end_date.

6 columns · 8 rows
project_id int project_name text department_id int start_date date end_date date status text
Table · assignments

One row per employee on a project, so employees and projects join many-to-many through this table.

5 columns · 26 rows
assignment_id int employee_id int project_id int role text hours_logged int

Best for

  • Self-joins: manager_id points back at employee_id in the same table.
  • Many-to-many joins from employees to projects through assignments.
  • Salary and headcount aggregates with GROUP BY and HAVING.
  • NULL handling: the CEO has no manager, and running projects have no end date.

Starter questions

  • Who reports to each manager, and who reports to nobody?
  • What is the average salary and headcount per department?
  • Which projects are still running, and how many hours has each logged?

Practice lessons