我想在数据库中为应用程序创建给定的公司结构,并希望根据结构遍历员工详细信息。问题如下。
当员工登录系统时,他应该能够看到员工在其级别下工作的详细信息。例如,如果“执行B”登录系统,他应该能够看到员工A,员工B,员工C和员工C的子员工的详细信息。
与此同时,工作人员C正向科长C报告,科长C只能查看员工C的详细信息,而不是他的子员工。这意味着,当部门主管C登录时,他可以查看他的子员工以及员工C.
但是,D部门负责人可以查看员工C的详细信息和他的子员工详细信息,因为他可以完全访问分支机构,从员工C开始。这意味着他可以查看他的子员工以及员工C及其子员工。
任何人都可以帮我实现这个结构和数据库中的访问级别以及如何以有效的方式查询它们吗?
答案 0 :(得分:3)
解决这种层次遍历问题的常用方法是使用一种名为访问数的技术,我在my answer to this question中对此进行了详细描述。使用访问数字,您可以轻松找到层次结构中任何位置下任何给定节点下方的所有节点的列表。
请注意,您仍然会使用员工表上的复制外键记录每个员工的直接上级报告。
对于您的情况,您还在常规报告层次结构之外进行虚线报告(C部分到C部门)。这意味着您将需要两种方法。第一种是使用访问号码进行定期报告,管理人员可以查看所有直接和间接报告,然后使用其他内容进行虚线报告。
虚线报告似乎有两种规则。一些虚线监督员可以看到分员,其他人只能看到他们的虚线直接报告。由于人们可以拥有多个虚线管理员,因此您需要添加交集表来记录这些虚线关系。此交集表还可以包含标志属性,指示虚线主管是否能够仅查看下一个虚线或该人及其所有下属。
无论哪种方式,虚线关系都直接记录在员工和他们的主管之间,并且定期报告关系(可能是间接的)由访问号码管理。
答案 1 :(得分:0)
您需要在员工上使用几个自联接表。 一个代表员工关系的主管。 第二个代表员工之间的同伴关系。
这是PostgreSQL的SQL
如果存在stackoverflow cascade,则删除模式;
create schema stackoverflow;
将search_path设置为stackoverflow,public;
创建表员工
(
id serial not null unique,
name text not null unique,
title text not null,
primary key ( id )
);
创建表格报告
(
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 )
);
创建或替换视图直接报告
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
从directreports,peer,employee
中选择* where
employee.id = peer.peerid
and peer.supervisorid = directreports."supervisor id";
插入员工(姓名,职位)
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;
以下是典型的查询
从员工中选择*;
从报告中选择*;
从directreports中选择*;
从同行中选择*;
从peerreports,employee中选择* employee.name ='d head';