SQL 语句技巧--递归查询机构和下属机构的用户数


SQL 语句技巧--递归查询机构和下属机构的用户数

     今天,一个同事说有个查询比较复杂,需求是:查询机构下的用户数(包括下面全部机构用户),同时还要统计下属机构的用户数。

 

     业务要求:要统计总公司下的用户,还要统计总公司下属的全部机构(技术部,分公司等)的用户数,

                  同时还要统计技术部,这时统计技术部的用户,还可能包含技术一部,技术二部,技术三部,可能技术一部下面还包含测试部等等部门的用户

                  依此类推,统计下面的技术一部,和技术一部下面的测试部

 

     同事说这样的话要在程序里递归查询全部机构,就可以得到结果,要写很多条sql语句,能不能用一条sql查询出来。

 

     后来自己试着用一个SQL语句统计出各个机构(包含下属机构)的用户数据,在SQL server 2005里有CTE实现递归查询。但只能查询一级的数据,如查询总公司的可以,但下面个部门,各个子公司就不好查询了总数了。而且在一条sql语句实现递归不太可能,这时考虑一下,发现用表值函数来实现,结合Cross apply来查询其下属机构的用户数。以下是实现T_SQL代码:

  表值函数:

复制代码
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--   =============================================
--  Author:  郑平
--  Create date: 2008年8月26日11: 14 : 15
--  Description: 返回机构下面的全部机构(包含本机构)
--   =============================================
CREATE FUNCTION subOrgs
(
  @orgid varchar(
32 )
)
RETURNS @tab table(id varchar(
32 ))
AS
BEGIN  
 ;
 with org(orgid)
 
as
 ( 
    select a.oid  from  orgunitlink a
   
where  a.pid = @orgid
   union all
    select c.oid 
   from orgunitlink c inner join org aa
   on aa.orgid
= c.pid
 )
  insert into @tab select orgid from org union select @orgid
  RETURN 
END
GO
复制代码
 

--查询sql 

复制代码
select t.objname,sum(y.num) num,t.id  from 
(select b.objname,count(
* ) num,b.id  from humres a inner join
orgunit b on a.orgid
= b.id 
inner join orgunitlink c on c.oid
= b.id   where  a.isdelete = 0  and
a.workstatus
<> ' 402881ea0b1c751a010b1cd2ae770008 '
group by b.objname,b.id,c.pid)t
 CROSS APPLY  subOrgs(id) f 
inner join 
(select b.objname,count(
* ) num,b.id  from humres a inner join
orgunit b on a.orgid
= b.id 
inner join orgunitlink c on c.oid
= b.id  where  a.isdelete = 0  and 
a.workstatus
<> ' 402881ea0b1c751a010b1cd2ae770008 '
group by b.objname,b.id,c.pid)
 y on y.id
= f.id  group by t.objname,t.id order by  2  desc
复制代码


 

 

     以上查询的速度很快,而且不使用递归查询数据库,是一个比较好的解决办法,下面是查询结果:

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM