通过使用CTE,统计每一个机构(部门)的人数信息现在只用一句SQL语句就搞定了,是不是很令人激动呢:)现在,我们来看一看这条语句:首先,统计的思路是从每一个人开始,得到一个人所在的机构,然后递归的得到该机构的父机构直到顶级机构(类似于这个人所属机构的一个路径).然后将这个人和路径上每个机构关联起来.所有,在SQL中,先定义一个CTE----EmployCTE,再定义这个CET递归的基(在这个例子中,是所有的员工).然后在递归部分,用部门表去连接这个CTE本身(他们之间的关联当然就是DepartmentID了.这样,就得到了所有员工所属机构的路径.然后,在通过以部门为单位,做一次聚集,就得到了所有机构的人数统计信息.(说得舌头都卷了,其实直接看SQL,很是简单明了:).with EmployCTE (DepartmentID)as ( --base case(Anchor member).Get all employee select DepartmentID from Employee union all --recursive member select depart.ParentID from Department depart join EmployCTE emp on depart.DepartmentID=emp.DepartmentID where depart.ParentID is not null)select * from Department depart --join all departmentleft join ( select EmployCTE.DepartmentID,count(*) as EmployeeSum from EmployCTE left join department depart on depart.DepartmentID=EmployCTE.DepartmentID group by EmployCTE.DepartmentID) empSum on depart.DepartmentID = empSum.DepartmentID
with DepartmentHierarchy (DepartmentID,DepartmentName,ParentID,HierarchyLevel)as ( --base case select DepartmentID,DepartmentName,ParentID,1 as HierarchyLevel from Department where parentID is null union all --recursive member select depart.DepartmentID,depart.DepartmentName,depart.ParentID,departHier.HierarchyLevel + 1 AS HierarchyLevel from Department depart inner join DepartmentHierarchy departHier on depart.ParentID=departHier.DepartmentID ),DepartAndEmp(DepartmentID,DepartmentName,ParentID,HierarchyLevel,num)as ( select * ,EmployeeNum=(select count(*) from Employee where DepartmentID=DepartmentHierarchy.DepartmentID) from DepartmentHierarchy)select * from DepartAndEmp
在上面这个例子中,用到了两个CTE,在使用多个CTE时,只用逗号将各个CTE分开即可.
另外,在使用CTE的过程中,也感觉到一些不方便的东西.例如:要想使用一个CTE,必须申明了他之后马上使用,否则,其后任何使用,会报"Invalid object"错误.有时我使用完某个CTE后,想再使用一次,麻烦就出来了,郁闷.也不知道MS是怎么想的还是我没找他其他办法?还有,在CTE的递归部分,不能使用诸如SUM,COUNT的聚集函数,这着实让我郁闷,不知道是处于实现上的原因还是性能上的原因.如果能使用的话,在做统计聚集的时候CTE将会更加简单方便
轉自:http://blog.csdn.net/LeON382/archive/2007/10/11/1820245.aspx