IF EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID('[dbo].[mps_calculate_relationship]') AND type = 'P')
DROP PROCEDURE [dbo].[mps_calculate_relationship]
GO
/***
**管理关系存在两种情况
**1.直接关系
**2.间接关系
**逻辑：1.根据设置的关系，建立处理队列
    2.“逐一” 寻找 “向上”、“向下”关系
    3.通过查询两个直接关系，若存在间接关系，将间接关系追加到处理队列中，并将其写入目标关系表中
    
***/
CREATE procedure [dbo].[mps_calculate_relationship] 
as
begin
  
  set nocount on      
  /*
  --测试数据
  truncate table [mps_employee_subusers]
  insert into [mps_employee_subusers] ( [cs_cuid] , [cs_subcuid]  )
  values 
  (2,23),
  (4,7),
  (8,1),
  (9,2),
  (9,3),
  (9,4),
  (1,9),
  (9,5),
  (1,2),
  (2,21),
  (21,1),
  (7,8),
  (1,3),
  (3,5),
  (2,3),
  (2,22)
   */
  
  declare @cuid bigint = 0
  declare @subcuid bigint = 0
  declare @rowIndex bigint = 1 
      
  --待处理的队列
  declare @temp_employee_subusers table (
    pkey bigint primary key identity(1,1), 
    cuid bigint ,
    sbcuid bigint,
    toDown int default 0,--寻找下级关系标识
    toUp int default 0 --寻找上级关系标识
  ) 
  --用于暂存待插入最终关系
  declare @temp_employee_subusers_copy table (cuidcp bigint ,sbcuidcp bigint) 
  --记录待处理的队列中，当做上级处理的ID,用来判断循环关系
  declare @DirectHead table (Dheadcuid bigint )
  --记录具体循环的关系，遇到循环关系就停止，最后通过迪卡积得到关系
  declare @circleEnd2Head table (endid bigint ,headid bigint) --尾》头 
  --先存临时表，最终再写入目标关系表
  declare @mps_employee_subusersreal table([cus_cuid] bigint , [cus_subcuid] bigint PRIMARY KEY CLUSTERED 
  (
    [cus_cuid] ASC,
    [cus_subcuid] ASC
  )) 
    
  --初始化队列
  insert into @temp_employee_subusers(cuid,sbcuid)
  select cs_cuid,cs_subcuid from [mps_employee_subusers] 
  
  --插入直接关系到目标表
  insert into @mps_employee_subusersreal( [cus_cuid] , [cus_subcuid])
  select cs_cuid,cs_subcuid from [mps_employee_subusers]-- order by cs_cuid asc,cs_subcuid asc 
      
  --逐一处理间接关系
  while(exists(select 1 from @temp_employee_subusers where pkey = @rowIndex ) )
  begin                           
      select top 1 @cuid = cuid,@subcuid =sbcuid from @temp_employee_subusers where pkey=@rowIndex    
      
      if(not exists(select 1 from @DirectHead where Dheadcuid = @cuid))
        insert into @DirectHead(Dheadcuid) values(@cuid)                                  
            
      --若存在向下关系
      while(exists(select 1 from @temp_employee_subusers son,@temp_employee_subusers crt where son.cuid = @subcuid and crt.toDown = 0 and crt.pkey = @rowIndex))
      begin
        --有重复，临时表去重复
        insert into @temp_employee_subusers_copy(cuidcp,sbcuidcp)             
        select  @cuid,s.sbcuid  from @temp_employee_subusers f,@temp_employee_subusers s
        where s.cuid = f.sbcuid 
        and f.sbcuid = @subcuid       
        and f.cuid = @cuid                  
                    
        delete  t from @temp_employee_subusers s,@temp_employee_subusers_copy t
        where   t.cuidcp = s.cuid and t.sbcuidcp = s.sbcuid
        
         
        delete t from @mps_employee_subusersreal s,@temp_employee_subusers_copy t where cuidcp = cus_cuid and cus_subcuid = sbcuidcp
        
        --插入间接关系到目标表
        insert into @mps_employee_subusersreal(cus_cuid,cus_subcuid)  
        select cuidcp,sbcuidcp from @temp_employee_subusers_copy 
        
        
        --插入间接关系到队列       
        insert into @temp_employee_subusers(cuid,sbcuid)  
        select cuidcp,sbcuidcp from @temp_employee_subusers_copy 
        
        delete @temp_employee_subusers_copy
                                      
        --记录循环节点  
        insert into @circleEnd2Head(endid,headid)
        select cuid,@cuid from @temp_employee_subusers ,@DirectHead  
          where cuid = @subcuid 
            and Dheadcuid = sbcuid
          
          
        update @temp_employee_subusers set toDown = 1 where pkey = @rowIndex  
                                                      
      end 
      
      --若存在向上关系
      while(exists(select 1 from @temp_employee_subusers father,@temp_employee_subusers crt where father.sbcuid = @cuid and crt.toUp = 0  and crt.pkey = @rowIndex))
      begin
        --有重复，临时表去重复
        insert into @temp_employee_subusers_copy(cuidcp,sbcuidcp)             
        select  f.cuid,s.sbcuid  from @temp_employee_subusers f,@temp_employee_subusers s
        where s.cuid = f.sbcuid 
        and f.sbcuid = @cuid        
        and s.cuid = @cuid
          
                              
        delete  t from @temp_employee_subusers s,@temp_employee_subusers_copy t
        where   t.cuidcp = s.cuid and t.sbcuidcp = s.sbcuid
                
        delete t from @mps_employee_subusersreal s,@temp_employee_subusers_copy t where cuidcp = cus_cuid and cus_subcuid = sbcuidcp
                                                    
        --插入间接关系到目标表
        insert into @mps_employee_subusersreal(cus_cuid,cus_subcuid)  
        select cuidcp,sbcuidcp from @temp_employee_subusers_copy 
        
        
        --插入间接关系到队列       
        insert into @temp_employee_subusers(cuid,sbcuid)  
        select cuidcp,sbcuidcp from @temp_employee_subusers_copy 
        
        delete @temp_employee_subusers_copy
                            
        --记录循环节点  
        insert into @circleEnd2Head(endid,headid)
        select cuid,@cuid from @temp_employee_subusers ,@DirectHead  
          where cuid = @subcuid 
            and Dheadcuid = sbcuid  
        update @temp_employee_subusers set toUp = 1 where pkey = @rowIndex                        
                                                                                      
      end 
            
      --删除直接关系              
      delete @temp_employee_subusers where cuid = @cuid and sbcuid = @subcuid
      
      set @cuid = 0
      set @subcuid = 0
      set @rowIndex = @rowIndex+1
      select top 1 @cuid = cuid,@subcuid =sbcuid from @temp_employee_subusers where pkey = @rowIndex  order by cuid asc,sbcuid asc  
                  
  end

  delete @temp_employee_subusers_copy 
    
  insert into @temp_employee_subusers_copy(cuidcp,sbcuidcp)
  select endid,cus_subcuid 
  from @circleEnd2Head,@mps_employee_subusersreal 
  where headid = cus_cuid 
  
  delete s from @temp_employee_subusers_copy t,@mps_employee_subusersreal s 
  where t.cuidcp = s.cus_cuid
  and t.sbcuidcp = s.cus_subcuid
  
  --truncate table mps_employee_subusersreal  
  
  DELETE mps_employee_subusersreal 
  where not exists(select 1 from  @mps_employee_subusersreal t 
                    where mps_employee_subusersreal.cus_cuid = t.cus_cuid 
                    and mps_employee_subusersreal.cus_subcuid = t.cus_subcuid) 
  
  delete  s
  from @mps_employee_subusersreal s
  where  exists(select 1 from  mps_employee_subusersreal t where s.cus_cuid = t.cus_cuid and s.cus_subcuid = t.cus_subcuid) 
  
      
  insert into mps_employee_subusersreal(cus_cuid,cus_subcuid)
  select  cus_cuid,cus_subcuid from @mps_employee_subusersreal

end