You need a couple of self-join tables on employee.
One represents the supervisor to employee relation.
The second represents the peer relationship between employees.
Here is the SQL for PostgreSQL
drop schema if exists stackoverflow cascade;
create schema stackoverflow;
set search_path to stackoverflow, public;
create table employee
(
id serial not null unique,
name text not null unique,
title text not null,
primary key ( id )
);
create table reports
(
supervisorid integer not null references employee ( id ) on delete cascade ,
subordinateid integer not null references employee ( id )
check ( supervisorid != subordinateid ),
unique ( supervisorid, subordinateid ),
unique( subordinateid )
);
create table peer
(
supervisorid integer not null references employee ( id ) on delete cascade ,
peerid integer not null references employee ( id )
check ( supervisorid != peerid ),
unique ( supervisorid, peerid )
);
create or replace view directreports as
select supervisor.id as "supervisor id",
supervisor.name as "supervisor name",
reporting.id as "employee id", reporting.name as "employee name"
from
employee supervisor, employee reporting , reports
where
supervisor.id = reports.supervisorid
and reporting.id = reports.subordinateid;
create or replace view peerreports as
select * from directreports, peer, employee
where
employee.id = peer.peerid
and peer.supervisorid = directreports."supervisor id";
insert into employee (name, title)
values ( 'c head', 'c head'),
( 'd head', 'd head'),
('c emp1', 'c emp1' ) ,
('c emp2', 'c emp2' ) ;
insert into reports
select employee.id as "supervisorid",
reportsto.id as "subordinateid"
from employee, employee reportsto
where employee.name = 'c head'
and reportsto.name in ('c emp1', 'c emp2' )
and reportsto.name != employee.name ;
insert into peer
select employee.id as "supervisorid",
peerto.id as "peer.peerid"
from employee, employee peerto
where employee.name = 'c head' and peerto.name = 'd head'
and employee.id != peerto.id;
Here are the typical queries
select * from employee;
select * from reports;
select * from directreports;
select * from peer;
select * from peerreports, employee
where employee.name= 'd head';