首页 新闻 会员 周边

sql server 递归取子级问题

0
悬赏园豆:20 [已解决问题] 解决于 2014-01-07 09:44

假设表:

id  pid
1  0
2  0
3  0
4  1
5  4
6  1
7  6
8  5

找到的一些方法只能处理成这样:

id  pid
1  0
2  0
3  0
4  1
6  1
5  4
7  6
8  5

我需要处理成这样:

id  pid
1  0
  4  1
    5  4
      8  5  --
  6  1
    7  6
2  0
3  0

有没有可能?

就是能不能在指定位置插入数据行?

4和6   插到1和2之间   5插到4和6之间  。。。。

小胤   *的主页 小胤 * | 初学一级 | 园豆:186
提问于:2014-01-06 11:54
< >
分享
最佳答案
0

id  pid
1  0
  4  1
    5  4
      8  5  --
  6  1
    7  6 
2  0 
3  0

有没有可能?

你这意思是不是就是 默认取得是父节点0下的子级1,2,3

然后1,2,3下如果有子级就继续取,子级下再有子级继续取,如此就是明显的递归。

 

 

就是能不能在指定位置插入数据行?

4和6   插到1和2之间   5插到4和6之间  。。。。

这两个什么意思 

其实看上去就是 你要在指定节点下添加子节点吧。

 

收获园豆:15
aehyok | 小虾三级 |园豆:1212 | 2014-01-06 12:21

 对,就是这样,但是我用找到的方法,查出来的数据  是:

1  0
2  0 
3  0
  4  1
  6  1
    5  4
    7  6 
      8  5 

比如取pid=0的  就会把123时取出来,无法实现指定节点下添加子节点

游标到是可以实现  不过不考虑游标。。。

小胤 * | 园豆:186 (初学一级) | 2014-01-06 12:58

@小胤 *: 你可以把你现在实现的方式贴出来看看。

aehyok | 园豆:1212 (小虾三级) | 2014-01-06 13:24

@aehyok: 

DECLARE @i INT 
        SET @i = 1 

        INSERT  INTO @t
                SELECT  @ID ,
                        @ID ,
                        0 --当前级,本级,如果不要的话可以注释掉或再加个参数来选择操作
        INSERT  INTO @t
                --TODO 
                SELECT  ID ,
                        ParentID ,
                        @i
                FROM    [Type]
                WHERE   ParentID = @ID 
     --上面这句,已经同时把123三个都插到@t表里了。     


--循环查询子级 WHILE @@rowcount <> 0 BEGIN SET @i = @i + 1 INSERT INTO @t SELECT a.ID , a.ParentID , @i FROM [Type] a , @t b WHERE a.ParentID = b.ID AND b.Layer = @i - 1 END
小胤 * | 园豆:186 (初学一级) | 2014-01-06 13:27

@小胤 *: 再优化一下应该就可以了。

你可以添加一个行号

INSERT  INTO @t
                --TODO 
                SELECT  ID ,
                        ParentID ,
                        @i
                FROM    [Type]
                WHERE   ParentID = @ID 
     --上面这句,已经同时把123三个都插到@t表里了。

添加一个行号,通过rownum

SELECT ROW_NUMBER() OVER(ORDER BY ordered DESC) AS rownum, ordered
FROM Orders
ORDER BY rownum DESC

这样再添加子级的时候,针对子级你也把父级的这个行号写进去,就代表子级也属于此行号,也就是做一个标识

比如 插入

第三列为行号

1  0     1
2  0     2
3  0     3

然后是你下面的子级

4  1     1
6  1     1
5  4      1
7  6      1
8  5      1

 

添加肯定还和你上面一样  

然后你再select 字段  from   表名  order  by  行号,父级ID,ID

感觉这个思路你可以试试。

 

aehyok | 园豆:1212 (小虾三级) | 2014-01-06 13:51

@aehyok: 

我不太明白你说得意思,按照我的理解,是1的行号是1然后1下面的子级行号都是1,是这意思吧?试了下还是不行,不过你这一提示,想到个方法,就是1的行号是1,那么4和6的行号就是11和12,就是用数字表示树结构,不过刚开始也是不行,Sort排序结果是按照数字的大小来的:

然后给格式化下,后面补零就行了,最终效果:

 

不过,假如说嵌套的子级很深,那格式化不是要补齐成好多位?20级就得20位。。。

小胤 * | 园豆:186 (初学一级) | 2014-01-07 09:41

@小胤 *: 你可以把SQL贴出来看看。

按照我的理解,是1的行号是1然后1下面的子级行号都是1,是这意思吧?  =======是这样的。

你只需要对第一个SQL进行行号设置,然后第二个SQL是通过联合查询插入的。。

aehyok | 园豆:1212 (小虾三级) | 2014-01-07 09:44

@aehyok: 

按照都是1的那种方法的话,结果是这样:

只要是1的子级,不管是多深的子级,行号都是1。。。

小胤 * | 园豆:186 (初学一级) | 2014-01-07 09:51

@小胤 *: 是的  所以你可以再查询一次

select 字段  from   表名  order  by  行号,父级ID,ID

aehyok | 园豆:1212 (小虾三级) | 2014-01-07 09:53

@aehyok: 

行号,父级ID,ID。。。。。。。。

小胤 * | 园豆:186 (初学一级) | 2014-01-07 09:56
其他回答(1)
0
收获园豆:5
幻天芒 | 园豆:37175 (高人七级) | 2014-01-06 13:48

结果为:

ID ParentID Layer
1   0   1
4   1   2
6   1   2
7   6   3
5   4   3
8   5   4

 

昨天试过CTE了,不过看你贴的地址里有个截图是实现成功的,就又试了下,还是不行,文章里的是因为数据少,嵌套少的关系吧,比如我上面的结果  如果只看前4条数据的话 ,看着是对的,但是后面的就不对了。。

支持(0) 反对(0) 小胤 * | 园豆:186 (初学一级) | 2014-01-07 08:57
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册