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.

Download this dataset, free

No account, no email, no attribution required — free for any use, including commercially. Take the single .sql file to load everything into PostgreSQL, MySQL, SQLite, DuckDB, or SQL Server, or grab the raw CSVs.

employee_directory.sqlAll 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 joiningemployees to itself. The reporting line runs three levels deep, 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

Schema · Employee DirectoryView dataset schema4 tables
Table · departments

One row per department.

4 columns · 5 rows
department_id intdepartment_name textlocation textannual_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 intfirst_name textlast_name textjob_title textdepartment_id intmanager_id inthire_date datesalary int
Table · projects

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

6 columns · 8 rows
project_id intproject_name textdepartment_id intstart_date dateend_date datestatus 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 intemployee_id intproject_id introle texthours_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 with this dataset

Guided lessons for this dataset are still being written. In the meantime, open it in the playground: the tables are already loaded, and the starter query is waiting in the editor.

Open Employee Directory in the playground →