SQL游标+递归查询客户子客户转换率

ALTER PROCEDURE  [dbo].[Account3YearsConversion ] as 
DECLARE @AccountId UNIQUEIDENTIFIER ,
    @yearbeforamountA int ,
    @yearbeforamountB int ,
    @lastyearamountA int,
    @lastyearamountB int,
    @yt_purchase_amountcloseA int ,
    @yt_purchase_amountcloseB int ,
    @yt_forecast_amountAdvancingA int ,
    @yt_purchase_amountAdvancingB int ,
    @nowdate int 
     SELECT @nowdate=DATEPART(year,Getdate())  
DECLARE mycursor CURSOR
FOR
    select accountid from account WHERE StateCode=0  and yt_sap_code is not null and yt_sap_code<>''
   
--打开游标  
OPEN mycursor      
    --从游标里取出数据赋值到我们刚才声明的变量中  
FETCH NEXT FROM mycursor INTO @AccountId
    --判断游标的状态  
    -- 0 fetch语句成功      
    ---1 fetch语句失败或此行不在结果集中      
    ---2 被提取的行不存在

    WHILE ( @@fetch_status = 0 ) 
        BEGIN 
             --前年转化率A
              WITH childAccount(accountid,ParentAccountId) as 
               ( 
                SELECT accountid,ParentAccountId FROM AccountBase WHERE accountid=@AccountId
                UNION ALL 
                SELECT A.accountid,A.ParentAccountId FROM AccountBase A,childAccount b 
                where a.ParentAccountId = b.accountid 
               )
               select    
                 @yearbeforamountA=(select ISNULL(sum(yt_purchase_amount),0) from Opportunity a join childAccount b on a.yt_arrive=b.accountid  
                where  DATEPART(year,DATEADD(MM,-2,a.yt_invoice_date))=@nowdate-2  and a.yt_status=100000002),
                @yearbeforamountB=(select ISNULL(sum(yt_purchase_amount),0) from Opportunity a join childAccount b on a.yt_arrive=b.accountid 
                where DATEPART(year,DATEADD(MM,-2,a.yt_require_date))=@nowdate-2 and 
                 (a.yt_status=100000002 or a.yt_status=100000003 or (a.yt_status=100000001 and a.yt_improve_winrate2=100000001))),
                 @lastyearamountA=(select ISNULL(sum(yt_purchase_amount),0) from Opportunity a join childAccount b on a.yt_arrive=b.accountid  
                where   DATEPART(year,DATEADD(MM,-2,yt_invoice_date))=@nowdate-1  and a.yt_status=100000002),
                 @lastyearamountB=(select ISNULL(sum(yt_purchase_amount),0) from Opportunity a join childAccount b on a.yt_arrive=b.accountid 
                where DATEPART(year,DATEADD(MM,-2,a.yt_require_date))=@nowdate-1 and 
                 (a.yt_status=100000002 or a.yt_status=100000003 or (a.yt_status=100000001 and a.yt_improve_winrate2=100000001))),
                 @yt_purchase_amountcloseA=(select ISNULL(sum(yt_purchase_amount),0)  from Opportunity a join childAccount b on a.yt_arrive=b.accountid 
                where DATEPART(year,DATEADD(MM,-2,a.yt_require_date))=@nowdate
                 and (a.yt_status=100000002  or (a.yt_status=100000001 and a.yt_improve_winrate2=100000001))),
                @yt_purchase_amountcloseB=(select ISNULL(sum(yt_purchase_amount),0)  from Opportunity a join childAccount b on a.yt_arrive=b.accountid  
                where  DATEPART(year,DATEADD(MM,-2,a.yt_require_date))=@nowdate  
                 and (a.yt_status=100000002 or a.yt_status=100000003 or (a.yt_status=100000001 and a.yt_improve_winrate2=100000001))),
                 @yt_forecast_amountAdvancingA=(select ISNULL(sum(yt_forecast_amount),0) from Opportunity a join childAccount b on a.yt_arrive=b.accountid  
                where   DATEPART(year,DATEADD(MM,-2,a.yt_require_date))=@nowdate
                and (a.yt_status=100000001 and a.yt_improve_winrate2!=100000001)),        
                 @yt_purchase_amountAdvancingB=(select ISNULL(sum(yt_purchase_amount),0) from Opportunity a join childAccount b on a.yt_arrive=b.accountid  
                where   DATEPART(year,DATEADD(MM,-2,a.yt_require_date))=@nowdate  
                and (a.yt_status=100000001 and a.yt_improve_winrate2!=100000001))
                                                            
           update account         
           set yt_yearbeforconversion =   Case @yearbeforamountB when 0
            then null 
             else  
              ltrim(Convert(numeric(9,2),@yearbeforamountA*100.0/@yearbeforamountB))+'%' 
              end,
               yt_lastyearconversion =  case @lastyearamountB when 0
            then null
            else
             ltrim(convert(numeric(9,2),@lastyearamountA*100.0/@lastyearamountB))+'%'
              end,              
               yt_thisyearcloseconversion = case @yt_purchase_amountcloseB when 0
               then null
               else 
               ltrim(convert(numeric(9,2),@yt_purchase_amountcloseA*100.0/@yt_purchase_amountcloseB))+'%' 
               end,        
               yt_thisyearadvancingconversion = case @yt_purchase_amountAdvancingB when 0
               then null
               else
                ltrim(convert(numeric(9,2),@yt_forecast_amountAdvancingA*100.0/@yt_purchase_amountAdvancingB))+'%' 
                end,
                yt_thisyearpredictconversion = case @yt_purchase_amountcloseB+@yt_purchase_amountAdvancingB when 0
                then null
                else
                ltrim(convert(numeric(9,2),(@yt_purchase_amountcloseA+@yt_forecast_amountAdvancingA)*100.0/(@yt_purchase_amountcloseB+@yt_purchase_amountAdvancingB)))+'%'
                end
           where  AccountId =@AccountId
           
           --用游标去取下一条客户  
           FETCH NEXT FROM mycursor  INTO @AccountId
        END  
    --关闭游标  
CLOSE mycursor  
    --撤销游标  
DEALLOCATE mycursor   
原文地址:https://www.cnblogs.com/zhaojingwei/p/4691831.html