• 转载 :SQL Server 2005 Recursion and WITH Clause


    原文

    Recursive queries have been added to T-SQL in SQL Server 2005 in the form of the WITH clause and CTE.  The books online documentation is pretty straight forward but a few people have asked me to work up a few useful samples to help get them going.  Simply copy/paste these samples into a query window and execute.

    Table of Contents Hierarchy
      set nocount on
     
      declare @Sample1 table 
      ( 
          RecordID int  Primary key NOT NULL ,
          ParentRecordID int,
          SortOrder int,
          Description nvarchar(100),
          Salary money
       )
     
     /* Start loading of test data */
      insert into @Sample1 values(1,null,null,'CEO',10)
      insert into @Sample1 values(2,1,1,'Vice Pres. Marketing',9)
      insert into @Sample1 values(3,1,2,'Vice Pres. Ops-',8)
      insert into @Sample1 values(4,2,1,'Marketing Director - Direct Mail',7)
      insert into @Sample1 values(5,2,2,'Marketing Director - TV',6)
      insert into @Sample1 values(6,1,3,'Vice Pres. - Research',5)
      insert into @Sample1 values(7,4,1,'Human Resources Director',4)
      insert into @Sample1 values(8,4,2,'Some other item',3)
      insert into @Sample1 values(9,6,1,'Research Analyst',2)
    
      set nocount off;
    
     with RecursionCTE (RecordID,ParentRecordID,SortOrder,Salary,TOC)
     as
     (
       select RecordID,ParentRecordID,SortOrder,Salary,
              convert(varchar(100),'') TOC
          from @Sample1
          where ParentRecordID is null
       union all
       select R1.RecordID,
              R1.ParentRecordID,
              R1.SortOrder,
              R1.Salary,
              case when DataLength(R2.TOC) > 0
                        then convert(varchar(100),R2.TOC + '.'
                                     + cast(R1.SortOrder as varchar(10))) 
                        else convert(varchar(100),
                                    cast(R1.SortOrder as varchar(10))) 
                        end as TOC
          from @Sample1 as R1
         join RecursionCTE as R2 on R1.ParentRecordID = R2.RecordID
      )
    
    select * from RecursionCTE order by ParentRecordID,SortOrder asc 
    
    Results
    
    
    RecordID    ParentRecordID SortOrder   Salary     TOC
    ----------- -------------- ----------- -----------------
    1           NULL           NULL        10.00                 
    2           1              1            9.00       1
    3           1              2            8.00       2
    6           1              3            5.00       3
    4           2              1            7.00       1.1
    5           2              2            6.00       1.2
    7           4              1            4.00       1.1.1
    8           4              2            3.00       1.1.2
    9           6              1            2.00       3.1
    
     
     
    
    Sum Up Subordinate Salaries of All Employees
    set nocount on
     
      declare @Sample1 table 
      ( 
          RecordID int  Primary key NOT NULL ,
          ParentRecordID int,
          SortOrder int,
          Description nvarchar(100),
          Salary money
       )
     
     /* Start loading of test data */
      insert into @Sample1 values(1,null,null,'CEO',10)
      insert into @Sample1 values(2,1,1,'Vice Pres. Marketing',9)
      insert into @Sample1 values(3,1,2,'Vice Pres. Ops-',8)
      insert into @Sample1 values(4,2,1,'Marketing Director - Direct Mail',7)
      insert into @Sample1 values(5,2,2,'Marketing Director - TV',6)
      insert into @Sample1 values(6,1,3,'Vice Pres. - Research',5)
      insert into @Sample1 values(7,4,1,'Human Resources Director',4)
      insert into @Sample1 values(8,4,2,'Some other item',3)
      insert into @Sample1 values(9,6,1,'Research Analyst',2)
    
    set nocount off;
    
     with RecursionCTE (RecordID,ParentRecordID,SortOrder,Salary)
     as
     (
       select RecordID,ParentRecordID,SortOrder,Salary
          from @Sample1
          where ParentRecordID is null
       union all
       select R1.RecordID,
              R1.ParentRecordID,
              R1.SortOrder,
              R1.Salary
          from @Sample1 as R1
         join RecursionCTE as R2 on R1.ParentRecordID = R2.RecordID
      )
     select sum(R1.salary) as Salary
       from @Sample1 as R1
       JOIN RecursionCTE as R2
       on R1.RecordID = R2.RecordID
    
    Results
    
    Salary
    ---------------------
    54.00
    
    (1 row(s) affected)
     
    
    Sum Up Subordinate Salaries of a Specific Employee
    set nocount on
     
      declare @Sample1 table 
      ( 
          RecordID int  Primary key NOT NULL ,
          ParentRecordID int,
          SortOrder int,
          Description nvarchar(100),
          Salary money
       )
     
     /* Start loading of test data */
      insert into @Sample1 values(1,null,null,'CEO',10)
      insert into @Sample1 values(2,1,1,'Vice Pres. Marketing',9)
      insert into @Sample1 values(3,1,2,'Vice Pres. Ops-',8)
      insert into @Sample1 values(4,2,1,'Marketing Director - Direct Mail',7)
      insert into @Sample1 values(5,2,2,'Marketing Director - TV',6)
      insert into @Sample1 values(6,1,3,'Vice Pres. - Research',5)
      insert into @Sample1 values(7,4,1,'Human Resources Director',4)
      insert into @Sample1 values(8,4,2,'Some other item',3)
      insert into @Sample1 values(9,6,1,'Research Analyst',2)
    
    set nocount off;
    
     with RecursionCTE (RecordID,ParentRecordID,SortOrder,Salary)
     as
     (
       select RecordID,ParentRecordID,SortOrder,Salary
          from @Sample1
          where ParentRecordID =2 -- specific employee id
       union all
       select R1.RecordID,
              R1.ParentRecordID,
              R1.SortOrder,
              R1.Salary
          from @Sample1 as R1
         join RecursionCTE as R2 on R1.ParentRecordID = R2.RecordID
      )
     select sum(R1.salary) as Salary
       from @Sample1 as R1
       JOIN RecursionCTE as R2
       on R1.RecordID = R2.RecordID
    
    Results:
    
    Salary
    ---------------------
    20.00
      
    
    Manager to Subordinate Salary Differential
     
      
    set nocount on
     
      declare @Sample1 table 
      ( 
          RecordID int  Primary key NOT NULL ,
          ParentRecordID int,
          SortOrder int,
          Description nvarchar(100),
          Salary money
       )
     
     /* Start loading of test data */
      insert into @Sample1 values(1,null,null,'CEO',10)
      insert into @Sample1 values(2,1,1,'Vice Pres. Marketing',9)
      insert into @Sample1 values(3,1,2,'Vice Pres. Ops-',8)
      insert into @Sample1 values(4,2,1,'Marketing Director - Direct Mail',7)
      insert into @Sample1 values(5,2,2,'Marketing Director - TV',6)
      insert into @Sample1 values(6,1,3,'Vice Pres. - Research',5)
      insert into @Sample1 values(7,4,1,'Human Resources Director',4)
      insert into @Sample1 values(8,4,2,'Some other item',3)
      insert into @Sample1 values(9,6,1,'Research Analyst',2)
    
    set nocount off;
    
     with RecursionCTE (RecordID,ParentRecordID,SortOrder,ParentSalary,Salary,Differential)
     as
     (
       select RecordID,ParentRecordID,SortOrder,
                convert(money,null) as ParentSalary,
                Salary,
                convert(money,null) as Differential
          from @Sample1
          where ParentRecordID is null
       union all
       select R1.RecordID,
                R1.ParentRecordID,
                R1.SortOrder,
                convert(money,R2.Salary) as ParentSalary,
                R1.Salary,
                convert(money,R2.Salary - R1.Salary) as Differential
          from @Sample1 as R1
         join RecursionCTE as R2 on R1.ParentRecordID = R2.RecordID
       
         
      )
    
    select * from RecursionCTE order by ParentRecordID,SortOrder asc 
    
    
    RecordID    ParentRecordID SortOrder   ParentSalary          Salary                Differential
    ----------- -------------- ----------- --------------------- --------------------- ---------------------
    1           NULL           NULL        NULL                  10.00                 NULL
    2           1              1           10.00                 9.00                  1.00
    3           1              2           10.00                 8.00                  2.00
    6           1              3           10.00                 5.00                  5.00
    4           2              1           9.00                  7.00                  2.00
    5           2              2           9.00                  6.00                  3.00
    7           4              1           7.00                  4.00                  3.00
    8           4              2           7.00                  3.00                  4.00
    9           6              1           5.00                  2.00                  3.00
    
      
    
  • 相关阅读:
    netty 服务端 启动阻塞主线程
    idea踩过的坑
    bat批量重命名
    图片上传
    TCP/IP入门指导
    CPU governor调节器汇总
    IT咨询顾问:一次吐血的项目救火
    python 数组
    Python字符串
    基于Python实现对各种数据文件的操作
  • 原文地址:https://www.cnblogs.com/philzhou/p/2059986.html
Copyright © 2020-2023  润新知