读书人

一条超难的树形结构表的sql请大家帮

发布时间: 2012-04-08 14:38:30 作者: rapoo

一条超难的树形结构表的sql,请大家帮忙
有一个表名为:T
结构如下:
id ---int
parentid---int 上层的父节点
sname--varchar(50)

如有以下数据:
id parentid sname
1 -1 根节点
2 1 节点1
3 1 节点2
4 2 节点3
5 2 节点4
6 3 节点5
7 3 节点6
7 6 节点7

假如:我要得到某个节点下所有的最底层的节点数据怎么实现:
如:我要得到id=3 的所有最底层的数据是:
id parentid sname
7 3 节点6
7 6 节点7
请大家多多帮忙,谢谢!





[解决办法]

SQL code
--测试数据CREATE TABLE tb(ID char(3),PID char(3),Name nvarchar(10))INSERT tb SELECT '001',NULL ,'山东省'UNION ALL SELECT '002','001','烟台市'UNION ALL SELECT '004','002','招远市'UNION ALL SELECT '003','001','青岛市'UNION ALL SELECT '005',NULL ,'四会市'UNION ALL SELECT '006','005','清远市'UNION ALL SELECT '007','006','小分市'GO--查询指定节点及其所有子节点的函数CREATE FUNCTION f_Cid(@ID char(3))RETURNS @t_Level TABLE(ID char(3),Level int)ASBEGIN    DECLARE @Level int    SET @Level=1    INSERT @t_Level SELECT @ID,@Level    WHILE @@ROWCOUNT>0    BEGIN        SET @Level=@Level+1        INSERT @t_Level SELECT a.ID,@Level        FROM tb a,@t_Level b        WHERE a.PID=b.ID            AND b.Level=@Level-1    END    RETURNENDGO--调用函数查询002及其所有子节点SELECT a.*FROM tb a,f_Cid('002') bWHERE a.ID=b.ID/*--结果ID   PID  Name       ------ ------- ---------- 002  001  烟台市004  002  招远市--*/
[解决办法]
SQL code
CREATE FUNCTION f_Pid(@ID char(3))RETURNS @t_Level TABLE(ID char(3),Level int)ASBEGIN    DECLARE @Level int    SET @Level=1    INSERT @t_Level SELECT @ID,@Level    WHILE @@ROWCOUNT>0    BEGIN        SET @Level=@Level+1        INSERT @t_Level SELECT a.PID,@Level        FROM tb a,@t_Level b        WHERE a.ID=b.ID            AND b.Level=@Level-1    END    RETURNENDGO--上面的用户定义函数可以处理一个节点有多个父节点的情况,对于标准的树形数据而言,由于每个节点仅有一个父节点,所以也可以通过下面的用户定义函数实现查找标准树形数据的父节点。CREATE FUNCTION f_Pid(@ID char(3))RETURNS @t_Level TABLE(ID char(3))ASBEGIN    INSERT @t_Level SELECT @ID    SELECT @ID=PID FROM tb    WHERE ID=@ID        AND PID IS NOT NULL    WHILE @@ROWCOUNT>0    BEGIN        INSERT @t_Level SELECT @ID        SELECT @ID=PID FROM tb        WHERE ID=@ID            AND PID IS NOT NULL    END    RETURNEND
[解决办法]
SQL code
create table tb(id int,parentid int,sname varchar(10))insert into tb select 1 , -1     ,    '根节点' insert into tb select 2 ,  1     ,    '节点1' insert into tb select 3 ,  1     ,    '节点2' insert into tb select 4 ,  2     ,    '节点3' insert into tb select 5 ,  2     ,    '节点4' insert into tb select 6 ,  3     ,    '节点5' insert into tb select 7 ,  3     ,    '节点6' insert into tb select 7 ,  6     ,    '节点7' goCREATE FUNCTION f_Cid(@ID int)RETURNS @t_Level TABLE(ID int,Level int)ASBEGIN    DECLARE @Level int    SET @Level=1    INSERT @t_Level SELECT @ID,@Level    WHILE @@ROWCOUNT>0    BEGIN        SET @Level=@Level+1        INSERT @t_Level SELECT a.ID,@Level        FROM tb a,@t_Level b        WHERE a.parentID=b.ID            AND b.Level=@Level-1    END    RETURNENDGOselect distinct a.* from f_cid(3) b ,tb awhere b.id=a.id  and not exists(select * from tb where parentid=b.id)godrop table tbdrop function f_cid/*id          parentid    sname      ----------- ----------- ---------- 7           3           节点67           6           节点7(所影响的行数为 2 行)*/
[解决办法]
-- sql 2005 可以直接查询
SQL code
;WITHTREE AS(    SELECT * FROM T    WHERE parentid = 3  -- 要查询的父 id    UNION ALL    SELECT T * FROM T, TREE    WHERE T.parentid = TREE.id)SELECT * FROM TREE 


[解决办法]

SQL code
create table tb(id int, parentid int, sname varchar(10))insert into tb values(1 , -1 ,        '根节点') insert into tb values(2 ,  1 ,        '节点1') insert into tb values(3 ,  1 ,        '节点2') insert into tb values(4 ,  2 ,        '节点3') insert into tb values(5 ,  2 ,        '节点4') insert into tb values(6 ,  3 ,        '节点5') insert into tb values(7 ,  3 ,        '节点6') insert into tb values(7 ,  6 ,        '节点7') go--查询指定节点及其所有子节点的函数 CREATE FUNCTION f_Cid(@ID int) RETURNS @t_Level TABLE(ID int,Level int) AS BEGIN   DECLARE @Level int   SET @Level=1   INSERT @t_Level SELECT @ID,@Level   WHILE @@ROWCOUNT>0   BEGIN     SET @Level=@Level+1     INSERT @t_Level SELECT a.ID,@Level     FROM tb a,@t_Level b     WHERE a.parentid=b.ID     AND b.Level=@Level-1   END   RETURN END GO SELECT distinct a.* FROM tb a,f_Cid(3) b WHERE a.ID=b.ID and a.id not in(select parentid from tb)drop table tbdrop function dbo.f_cid/*id          parentid    sname      ----------- ----------- ---------- 7           3           节点67           6           节点7(所影响的行数为 2 行)*/ 

读书人网 >SQL Server

热点推荐