我有以下表格:
Employees
-------------
ClockNo int
CostCentre varchar
Department int
和
Departments
-------------
DepartmentCode int
CostCentreCode varchar
Parent int
部门可以有其他部门作为父部门,这意味着存在无限的层次结构。所有部门都属于一个成本中心,因此总是有一个
CostCentreCode
.如 parent = 0
这是一个顶级部门员工必须拥有
CostCentre
值但可能有 Department
0 表示他们不在一个部门我想尝试和生成的是一个查询,最多可以提供四个层次结构。像这样:
EmployeesLevels
-----------------
ClockNo
CostCentre
DeptLevel1
DeptLevel2
DeptLevel3
DeptLevel4
我已经设法得到一些东西来显示自己的部门结构,但我无法弄清楚如何在不创建重复员工行的情况下将其链接到员工:
SELECT d1.Description AS lev1, d2.Description as lev2, d3.Description as lev3, d4.Description as lev4
FROM departments AS d1
LEFT JOIN departments AS d2 ON d2.parent = d1.departmentcode
LEFT JOIN departments AS d3 ON d3.parent = d2.departmentcode
LEFT JOIN departments AS d4 ON d4.parent = d3.departmentcode
WHERE d1.parent=0;
SQL 创建结构和一些示例数据:
CREATE TABLE Employees(
ClockNo integer NOT NULL PRIMARY KEY,
CostCentre varchar(20) NOT NULL,
Department integer NOT NULL);
CREATE TABLE Departments(
DepartmentCode integer NOT NULL PRIMARY KEY,
CostCentreCode varchar(20) NOT NULL,
Parent integer NOT NULL
);
CREATE INDEX idx0 ON Employees (ClockNo);
CREATE INDEX idx1 ON Employees (CostCentre, ClockNo);
CREATE INDEX idx2 ON Employees (CostCentre);
CREATE INDEX idx0 ON Departments (DepartmentCode);
CREATE INDEX idx1 ON Departments (CostCentreCode, DepartmentCode);
INSERT INTO Employees VALUES (1, 'AAA', 0);
INSERT INTO Employees VALUES (2, 'AAA', 3);
INSERT INTO Employees VALUES (3, 'BBB', 0);
INSERT INTO Employees VALUES (4, 'BBB', 4);
INSERT INTO Employees VALUES (5, 'CCC', 0);
INSERT INTO Employees VALUES (6, 'AAA', 1);
INSERT INTO Employees VALUES (7, 'AAA', 5);
INSERT INTO Employees VALUES (8, 'AAA', 15);
INSERT INTO Departments VALUES (1, 'AAA', 0);
INSERT INTO Departments VALUES (2, 'AAA', 1);
INSERT INTO Departments VALUES (3, 'AAA', 1);
INSERT INTO Departments VALUES (4, 'BBB', 0);
INSERT INTO Departments VALUES (5, 'AAA', 3);
INSERT INTO Departments VALUES (12, 'AAA', 5);
INSERT INTO Departments VALUES (15, 'AAA', 12);
这给出了以下结构(方括号中的员工时钟编号):
Root
|
|---AAA [1]
| \---1 [6]
| |---2
| \---3 [2]
| \---5 [7]
| \---12
| \---15 [8]
|
|---BBB [3]
| \---4 [4]
|
\---CCC [5]
查询应返回以下内容:
ClockNo CostCentre Level1 Level2 Level3 Level4
1 AAA
2 AAA 1 3
3 BBB
4 BBB 4
5 CCC
6 AAA 1
7 AAA 1 3 5
8 AAA 1 3 5 12 *
*
在员工 8 的情况下,他们处于级别 5。理想情况下,我想显示所有级别到 4 级,但我很高兴在这种情况下只显示 CostCentre
最佳答案
当我们加入表时,当我们找到属于上一级员工的适当部门时,我们应该停止进一步遍历路径。
当 Employee.Department=0 时,我们也有异常(exception)情况。在这种情况下我们不应该加入任何部门,因为在这种情况下部门是根。
我们只需要选择包含其中一个级别的员工部门的那些记录。
如果员工的部门级别大于 4,我们应该扩展所有 4 个级别的部门并按原样显示它们(即使无法达到所需的部门级别并且没有在扩展的部门中找到它)。
select e.ClockNo,
e.CostCentre,
d1.DepartmentCode as Level1,
d2.DepartmentCode as Level2,
d3.DepartmentCode as Level3,
d4.DepartmentCode as Level4
from Employees e
left join Departments d1
on e.CostCentre=d1.CostCentreCode
and d1.Parent=0
and ((d1.DepartmentCode = 0 and e.Department = 0) or e.Department <> 0)
left join Departments d2
on d2.parent=d1.DepartmentCode
and (d1.DepartMentCode != e.Department and e.Department<>0)
left join Departments d3
on d3.parent=d2.DepartmentCode
and (d2.DepartMentCode != e.Department and e.Department<>0)
left join Departments d4
on d4.parent=d3.DepartmentCode
and (d3.DepartMentCode != e.Department and e.Department<>0)
where e.Department=d1.DepartmentCode
or e.Department=d2.DepartmentCode
or e.Department=d3.DepartmentCode
or e.Department=d4.DepartmentCode
or e.Department=0
or (
(d1.DepartmentCode is not null) and
(d2.DepartmentCode is not null) and
(d3.DepartmentCode is not null) and
(d4.DepartmentCode is not null)
)
order by e.ClockNo;
关于sql - 如何从自引用表中确定每个人的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36647523/