• 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


     
     

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

  • 相关阅读:
    Using join buffer (Block Nested Loop)调优
    训练日志
    threejs对象控制
    js保留4位小数
    batchsize 为4时,显卡使用效率
    QMatrix4x4
    QHostInfo
    yolov5训练表示识别模型日志记录
    yolov5 train log
    yolov5模型训练过程中显卡使用率查询——记录
  • 原文地址:https://www.cnblogs.com/zping/p/1276505.html
Copyright © 2020-2023  润新知