首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 一条超难的树形结构表的sql,请大家帮忙 [已结贴,结贴人:BlackCodeBoy]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 10:19:43 楼主
    有一个表名为: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
    请大家多多帮忙,谢谢!


    100  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 10:22:161楼 得分:30
    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) 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.PID=b.ID AND b.Level=@Level-1 END RETURN END GO --调用函数查询002及其所有子节点 SELECT a.* FROM tb a,f_Cid('002') b WHERE a.ID=b.ID /*--结果 ID PID Name ------ ------- ---------- 002 001 烟台市 004 002 招远市 --*/
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 10:24:482楼 得分:20
    SQL code
    CREATE FUNCTION f_Pid(@ID char(3)) RETURNS @t_Level TABLE(ID char(3),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.PID,@Level FROM tb a,@t_Level b WHERE a.ID=b.ID AND b.Level=@Level-1 END RETURN END GO --上面的用户定义函数可以处理一个节点有多个父节点的情况,对于标准的树形数据而言,由于每个节点仅有一个父节点,所以也可以通过下面的用户定义函数实现查找标准树形数据的父节点。 CREATE FUNCTION f_Pid(@ID char(3)) RETURNS @t_Level TABLE(ID char(3)) AS BEGIN 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 RETURN END
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 10:25:243楼 得分:0
    第一个是查找子节点的 

    第二个是查找父节点的
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • liangCK
    • 等级:
    发表于:2008-05-06 10:27:234楼 得分:20
    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' 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 f_cid(3) b ,tb a where b.id=a.id and not exists(select * from tb where parentid=b.id) go drop table tb drop function f_cid /* id parentid sname ----------- ----------- ---------- 7 3 节点6 7 6 节点7 (所影响的行数为 2 行) */
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 10:28:275楼 得分:0
    这个貌似深度排序广度排序的展树函数,csdn上很多~~~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 10:32:386楼 得分:20
    -- sql 2005 可以直接查询
    SQL code
    ;WITH TREE AS( SELECT * FROM T WHERE parentid = 3 -- 要查询的父 id UNION ALL SELECT T * FROM T, TREE WHERE T.parentid = TREE.id ) SELECT * FROM TREE
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dawugui
    • 等级:
    发表于:2008-05-06 10:33:497楼 得分:10
    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 tb drop function dbo.f_cid /* id parentid sname ----------- ----------- ---------- 7 3 节点6 7 6 节点7 (所影响的行数为 2 行) */
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • utpcb
    • 等级:
    发表于:2008-05-06 10:43:218楼 得分:0
    WITH
    TREE AS(
        SELECT * FROM T
        WHERE parentid = 3  -- 要查询的父 id
        UNION ALL
        SELECT T * FROM T, TREE
        WHERE T.parentid = TREE.id
    )
    SELECT * FROM TREE


    2005的这个方法最好
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 10:49:389楼 得分:0
    Mark.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ojuju10
    • 等级:
    发表于:2008-05-06 11:00:4510楼 得分:0
    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' go alter 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 delete a from @t_level a where exists(select 1 from @t_level where a.level<level) RETURN END GO select a.* from f_cid(3) b ,tb a where b.id=a.id go drop table tb drop function f_cid
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ojuju10
    • 等级:
    发表于:2008-05-06 11:04:3211楼 得分:0

    with cet
    as
    (
    select * from tb
    where id=3
    union all
    select a.* from tb a,cet b
    where b.id=a.parentid
    )
    select * from cet
    where id <>3
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 11:56:1212楼 得分:0
    create table #c(id int,parentid int,sname varchar(10))
    insert into #c select 1 , -1     ,    '根节点' 
    insert into #c select 2 ,  1     ,    '节点1' 
    insert into #c select 3 ,  1     ,    '节点2' 
    insert into #c select 4 ,  2     ,    '节点3' 
    insert into #c select 5 ,  2     ,    '节点4' 
    insert into #c select 6 ,  3     ,    '节点5' 
    insert into #c select 7 ,  3     ,    '节点6' 
    insert into #c select 7 ,  6     ,    '节点7' 
    go

    WITH cet AS( 
        SELECT * FROM #c 
        WHERE parentid = 3  -- 要查询的父 id 
        UNION ALL 
        SELECT a.* FROM #c a inner join cet b
        on a.parentid = b.id 

    SELECT * FROM cet where id not in (select parentid from cet)
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 15:23:5213楼 得分:0
    sql吗?看不懂耶~~还要多多努力!!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • fuanwei
    • 等级:
    发表于:2008-05-06 16:40:4314楼 得分:0
    SQL code
    drop table tb 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 8 , 6 , '节点7' go alter FUNCTION f_Cid(@ID int) RETURNS @t_Level TABLE(Level int) AS BEGIN DECLARE @Level int set @Level=0 if exists(select * from tb where parentid=@ID) begin INSERT @t_Level select id from tb where parentid=@ID while exists(select * from tb where parentid=@ID and id>@Level) begin set @Level=(select top 1 id from tb where parentid=@ID and id>@Level) --set @ID=@Level INSERT @t_Level select Level from dbo.f_Cid(@Level) end end RETURN END GO select * from f_cid(3)

    变换一下就行了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zuo_hy
    • 等级:
    发表于:2008-05-06 20:40:2015楼 得分:0
    没弄懂,根据表结构树如下:
       根
       / \
      1   2
         / \
        3   4
       / \
      5  6
         /
        7.
    假如:我要得到某个节点下所有的最底