精通SqlServer2005学习笔记-----公用表表达式(CTE)

      CTE类似非持久化的视图,它是查询中定义的非持久化结果集,在定义域内仅定义一次可以无数次的使用,在查询的生命周期内一直存在。

    一:语法定义

        with<name of your CTE>(<Column names>) as ( <actual query>)

        select * from  <name of your CTE>

 

    二:主要功能及应用场景:

     (1) 应用在要创建一个临时表或视图 用后抛弃他  可以用CTE替代  优点:把有关联合的复杂性限制在CTE 中,从而可以简化代码  还可以在查询中减少一些自我关联,减少逻辑混淆的可能性

       比如重复的产品名称拥有不同的产品编号 如果运行一个查找重复值的查询,如果运行一个查找重复值的查询,该查询会返回所有记录,这就增加了删除重复的难度。

 

   select *from Products where Product_ID not in

   (select min(product_ID) from Products as p where Products.Priduct_name=p.Product_name)

  修改成CTE

  with CTEminiProductRecords as

  ( select min(Product_ID) as Product_ID,Product_Name From products

     Group By Product_Name having Count(*)>1

  )    

 select * from Products joun CTEMinProductRecords on      Products.product_name=CTEMinProductRecords .product_Name and     Products.Product_ID>CTEMinProductRecords.priduct_ID

 

     (2) 另一个主要功能是用CTE实现递归查询  例如: 对树结构数据分层查询时优势非常明显

          语法:

           with SimpleRecursive(field names)

           as

           (<select statement for the anchor menmber> ---定位成员 非递归 仅被调用一次

            union all

            <select statement for the  Recursive Member>----递归成员  重复调用 直到查询不再返回数据行为止

            )

        select * from SimpleRecursive

        递归CTE查询示例

        创建一个树表

        create table Employee_Tree (Employee_NM nvarchar(50),Employee_ID int primary key, reportto int)

       插入一些数据 生成一个数据报告

        insert into Employee_Tree Values('Richard',1,Null)
        insert into Employee_Tree Values('Stephen',2,1)
        insert into Employee_Tree Values('Clemens',3,2)
        insert into Employee_Tree Values('malek',4,2)
        insert into Employee_Tree Values('Giksin',5,4)
        insert into Employee_Tree Values('Kimberly', 6,1)
        insert into Employee_Tree Values('Ramesh',7,5)

       返回Stephen(Employee_ID=2)报告的所有成员以及向Stephen的下属报告所有员工

 

with Simplerecursive(Employee_NM,Employee_ID,ReportTo,SubLevel) as
(select Employee_NM,Employee_ID,ReportTo,0 From Employee_Tree where Employee_ID=2
union all select  p.Employee_NM,p.Employee_ID,p.ReportTo,SubLevel+1 from Employee_Tree p inner join
Simplerecursive a on a.Employee_ID=p.ReportTo)

select sr.Employee_NM as Employee,et.Employee_NM as boss from  simplerecursive sr inner join Employee_Tree et on sr.reportto=et.employee_ID and  SubLevel<=2

其中 sublevel 是限制级数 

还以用option(maxrecursion 2) 超出指定限制时会报异常

  

  

 

你可能感兴趣的:(sqlserver2005)