我个人认为cte最好用的地方是创建递归查询,下面演示一下这功能:现有一数据结构如下:这些数据存放在表Co_ItemNameSet中,表结构和部分数据如下:ItemId ParentItemId ItemName2 0 管理费用3 0 销售费用4 0 财务费用5 0 生产成本35 5 材料36 5 人工37 5 制造费用38 35 原材料39 35 主要材料40 35 间辅材料41 36 工资42 36 福利43 36 年奖金现在需求是:我想查询ItemId=2,也就是管理费用和其下属所有节点的信息通过CTE可以很简单达到需求要的数据为了体现CTE的方便性,我特意也写了一个SQL 2000版本的解决方法,先看看SQL 2000是怎么解决这个问题的复制代码代码如下:--SQL 2000版本DECLARE @i INTSELECT @i=2;/*使用临时表作为堆栈来跟踪所有正在处理中的项目(已经开始但尚未结束)。某个项目一旦处理完毕,将被从堆栈中删除。当发现新的项目时,这些项目将被添加到堆栈中。*/CREATE TABLE #tem([ItemId] [INT] NOT NULL,[level] INT);/*存放结果*/CREATE TABLE #list([ItemId] [INT] NOT NULL,[ParentItemId] [INT] NOT NULL DEFAULT ((0)),[ItemName] [nvarchar](100) NOT NULL DEFAULT (''),[level] INT);INSERT INTO #tem([ItemId],[level])SELECT ItemId,1FROM Co_ItemNameSetWHERE itemid=@iINSERT INTO #list([ItemId],[ParentItemId],[ItemName],[level])SELECT ItemId,ParentItemId,ItemName,1FROM Co_ItemNameSetWHERE itemid=@iDECLARE @level INTSELECT @level=1DECLARE @current INTSELECT @current=0/*当 @level 大于 0 时,执行以下步骤:⒈如果当前级别 (@level) 的堆栈中有项目,就选择其中一个,并称之为 @current。⒉从堆栈中删除该项目以免重复处理它,然后将其所有子项目添加到堆栈的下一级 (@level + 1) 中。⒊如果有子项目 (IF @@ROWCOUNT > 0),则下降一级处理它们 (@level = @level + 1);否则,继续在当前级别上处理。⒋最后,如果在当前级别的堆栈中没有待处理的项目,则返回到上一级,看上一级是否有待处理的项目 (@level = @level - 1)。当再没有上一级时,则完毕。*/WHILE(@level>0)BEGINSELECT @current=ItemIdFROM #temWHERE [level]=@levelIF @@ROWCOUNT>0BEGIN--从堆栈中删除该项目以免重复处理它DELETE FROM #temWHERE [level]=@level and ItemId=@current--将其所有子项目添加到堆栈的下一级 (@level + 1) 中。INSERT INTO #tem([ItemId],[level])SELECT [ItemId],@level+1FROM Co_ItemNameSetWHERE ParentItemId=@current--将其所有子项目添加INSERT INTO #list([ItemId],[ParentItemId],[ItemName],[level])SELECT [ItemId],[ParentItemId],[ItemName],@level+1FROM Co_ItemNameSetWHERE ParentItemId=@currentIF @@rowcount>0BEGINSELECT @level=@level+1ENDENDELSEBEGINSELECT @level=@level-1ENDEND--显示结果SELECT * FROM #listDROP TABLE #temDROP TABLE #listgo结果如下:ItemId ParentItemId ItemName level2 0 管理费用 152 2 汽车费用 255 2 招聘费 256 2 排污费 253 52 燃料 354 52 轮胎 3大家看到sql 2000 解决这个问题比较麻烦,要实现这需求编写的代码比较多,比较复杂现在好了,在sql2005 中通过CTE的递归特点可以2步就实现.得到同样的结果,sql2005 的CTE代码简单了许多.这就是CTE支持递归查询的魅力。请看下面的代码:复制代码代码如下:--sql2005版本DECLARE @i INTSELECT @i=2;WITH Co_ItemNameSet_CTE(ItemId,ParentItemId,ItemName,Level)ASSELECT ItemId,ParentItemId,ItemName,1 AS [Level]FROM Co_ItemNameSetWHERE itemid=@iUNION ALLSELECT c.ItemId,c.ParentItemId,c.ItemName,[Level] + 1FROM Co_ItemNameSet c INNER JOIN Co_ItemNameSet_CTE ctON c.ParentItemId=ct.ItemIdSELECT * FROM Co_ItemNameSet_CTEgoCustomerTerminalEquipment的缩写CTE(CustomerTerminalEquipment),用户终端设备.