UDF在层次型数据处理中的妙用之三

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
三、计算合计数和子树深度

  现在来看几个需要窍门才能解决的问题——如果不用递归就很难解决的问题。假定我们想要得到从指定管理员开始的特定子树下所有雇员的薪水总额。Listing4显示了如何用dbo.ufn_GetSubtreeSalary函数来完成这个任务。


LISTING4:计算子树的合计数

CREATEFUNCTIONdbo.ufn_GetSubtreeSalary
(
@mgridASint
)
RETURNSint
AS
BEGIN

RETURN(SELECTSalary
FROMEmployeesWHEREempid=@mgrid)+
CASE
WHENEXISTS(SELECT*FROMEmployeesWHEREmgrid=@mgrid)THEN
(SELECTSUM(dbo.ufn_GetSubtreeSalary(empid))
FROMEmployees
WHEREmgrid=@mgrid)
ELSE0
END
END


  注意dbo.ufn_GetSubtreeSalary函数非常简短;虽然我们面临的任务很复杂,但函数只包含一个RETURN语句。dbo.ufn_GetSubtreeSalary函数查询指定管理员的薪水,再加上每一个管理员直接下属所包含子树的薪水总和。现在,试着用这个新的函数计算从Janet(empid是3)开始的子树的薪水总额,答案将是20000:

SELECTdbo.ufn_GetSubtreeSalary(3)
  用类似的方法可以计算子树的深度,如Listing5所示。dbo.ufn_GetSubtreeDepth函数也返回一个CASE表达式的结果,但两者的代码有所不同。


LISTING5:计算子树的深度

CREATEFUNCTIONdbo.ufn_GetSubtreeDepth
(
@mgridASint
)
RETURNSint
AS
BEGIN

RETURNCASE
WHENEXISTS(SELECT*FROMEmployeesWHEREmgrid=@mgrid)
THEN1+(SELECTMAX(dbo.ufn_GetSubtreeDepth(empid))
FROMEmployees
WHEREmgrid=@mgrid)
WHENEXISTS(SELECT*FROMEmployeesWHEREempid=@mgrid)
THEN1
ELSENULL
END
END


  CASE表达式先检查指定的管理员是否有下属。如果有下属,函数返回1加上该管理员直接下属子树的最大深度——因此,这里出现了递归;如果指定的管理员没有下属,CASE表达式确定该管理员是否存在。如存在,则函数返回1(对于没有下属的管理员,他的深度是1);如果该管理员不存在,则CASE表达式返回NULL。现在,试验一下这个函数,提供Nancy的雇员ID(Nancy是最高级别的老板),计算整棵树的深度。计算结果将是5,它表明整个组织结构分5层。


SELECTdbo.ufn_GetSubtreeDepth(1)

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值