示例问题如下:
表结构:
IdParentId
10
21
32
......针对该表结构解释如下:
1的父节点为0,
2的父节点为1,
3的父节点为2
......
以此类推,要求给定一个父节点的值,比如1,
用sql语句查询的到该父结点下的所有子节点 下面的sql是在sqlServer下调试通过的,如果是Oracle,则有ConnectBy可以实现.
建立测试表: DropTableDbTree CreateTableDbTree ( [Id]Int,[Name]NVarChar(20),[ParentId]Int )
插入测试数据: InsertIntoDbTree([Id],[ParentId])Values(1,0) InsertIntoDbTree([Id],[ParentId])Values(2,1) InsertIntoDbTree([Id],[ParentId])Values(3,[ParentId])Values(4,3) InsertIntoDbTree([Id],[ParentId])Values(5,4) InsertIntoDbTree([Id],[ParentId])Values(6,7) InsertIntoDbTree([Id],[ParentId])Values(8,5) 实现方法一:
代码如下: Declare@IdInt Set@Id=1---在次修改父节点 SelectInto#TempFromDbTreeWhereParentIdIn(@Id) SelectInto#AllRowFromDbTreeWhereParentIdIn(@Id)--1,2
WhileExists(SelectFrom#Temp) Begin SelectInto#Temp2From#Temp TruncateTable#Temp
InsertInto#TempSelectFromDbTreeWhereParentIdIn(SelectIdFrom#Temp2) InsertInto#AllRowSelectFrom#Temp DropTable#Temp2 End SelectFrom#AllRowOrderById
DropTable#Temp DropTable#AllRow
实现方法二:
代码如下: CreateTable#AllRow ( IdInt,ParentIdInt )
Declare@IdInt Set@Id=1---在次修改父节点
Delete#AllRow
--顶层自身 InsertInto#AllRow(Id,ParentId)Select@Id,@Id
While@@RowCount>0 Begin InsertInto#AllRow(Id,ParentId) SelectB.Id,A.Id From#AllRowA,DbTreeB WhereA.Id=B.ParentIdAnd NotExists(SelectIdFrom#AllRowWhereId=B.IdAndParentId=A.Id) End
DeleteFrom#AllRowWhereId=@Id SelectFrom#AllRowOrderById DropTable#AllRow
实现方法三:
代码如下: 在sqlServer2005中其实提供了CTE[公共表表达式]来实现递归: 关于CTE的使用请查MSDN Declare@IdInt Set@Id=3;---在次修改父节点
WithRootNodeCTE(Id,ParentId) As ( SelectId,ParentIdFromDbTreeWhereParentIdIn(@Id) UnionAll SelectDbTree.Id,DbTree.ParentIdFromRootNodeCTE InnerJoinDbTree OnRootNodeCTE.Id=DbTree.ParentId )
Select*FromRootNodeCTE