我有以下表格:
Employees ------------- ClockNo int CostCentre varchar Department int
和
Departments ------------- DepartmentCode int CostCentreCode varchar Parent int
部门可以将其他部门作为父母,这意味着存在无限的等级.所有部门都属于成本中心,因此始终具有CostCentreCode.如果parent = 0,则它是顶级部门
员工必须具有CostCentre值,但可能具有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要创建Structure和一些示例数据:
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,3); INSERT INTO Employees VALUES (3,'BBB',0); INSERT INTO Employees VALUES (4,4); INSERT INTO Employees VALUES (5,'CCC',0); INSERT INTO Employees VALUES (6,1); INSERT INTO Employees VALUES (7,5); INSERT INTO Employees VALUES (8,15); INSERT INTO Departments VALUES (1,0); INSERT INTO Departments VALUES (2,1); INSERT INTO Departments VALUES (3,1); INSERT INTO Departments VALUES (4,0); INSERT INTO Departments VALUES (5,3); INSERT INTO Departments VALUES (12,5); INSERT INTO Departments VALUES (15,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级.理想情况下,我希望将所有级别显示为level4,但我很高兴在这种情况下显示CostCentre
解决方法
SunnyMagadan的查询很好.但是,根据部门中的员工数量,您可能希望尝试以下方法,使DB优化器有机会仅为部门遍历部门层次结构而不是为部门中的每个员工重复一次.
SELECT e.ClockNo,e.CostCentre,Level1,Level2,Level3,Level4 FROM Employees e LEFT JOIN (SELECT d1.departmentcode,d1.CostCentreCode,coalesce (d4.departmentcode,d3.departmentcode,d2.departmentcode,d1.departmentcode) AS Level1,case when d4.departmentcode is not null then d3.departmentcode when d3.departmentcode is not null then d2.departmentcode when d2.departmentcode is not null then d1.departmentcode end as Level2,case when d4.departmentcode is not null then d2.departmentcode when d3.departmentcode is not null then d1.departmentcode end as Level3,case when d4.departmentcode is not null then d1.departmentcode end as Level4 FROM departments AS d1 LEFT JOIN departments AS d2 ON d1.parent = d2.departmentcode LEFT JOIN departments AS d3 ON d2.parent = d3.departmentcode LEFT JOIN departments AS d4 ON d3.parent = d4.departmentcode) d ON d.DepartmentCode = e.Department AND d.CostCentreCode = e.CostCentre ;
编辑关于5级部门.
任何固定步骤查询都无法获得前4个级别.因此,更改上面的查询只是为了标记它们,例如-1.
,case when d4.Parent > 0 then NULL else coalesce (d4.departmentcode,d1.departmentcode) end AS Level1
等等.