2012-08-16 174 views
3

为了我和分层数据的工作和使用递归CTE列出的项目是这样的:递归CTE由

Eletronics 
    Televisions 
     Tube 
     LCD 
     Plasma 
    Portable Electronic 
     MP3 Players 
      Flash 
     CD Player 
     Two Way Radios 

我的问题是:
如何做到这一点通过列表标题排序并尊重层次?

像这样:

Eletronics 
    Portable Electronic 
     CD Player 
     MP3 Players 
      Flash 
     Two Way Radios 
    Televisions 
     LCD 
     Plasma 
     Tube 

韩国社交协会

+3

我们怎样才能在没有看到代码的情况下提供帮助 – Bort 2012-08-16 00:56:52

+0

数据库软件及其版本的选择对可能的解决方案有相当大的影响。 What'cha runnin'? – HABO 2012-08-16 01:24:01

+1

[CTE的真实递归?]的可能的重复?(http://stackoverflow.com/questions/11636420/a-real-recursion-with-cte) – 2012-08-16 04:24:46

回答

1

这里是我几乎完成了我想要的代码。现在 的问题是递减订购

declare @tab table(
    id int identity(1,1) 
    ,id_parent int 
    ,name_product varchar(100) 
) 

insert into @tab 
select null, 'Eletronics' 
union all 
select 1, 'Televisions' 
union all 
select 2, 'Tube' 
union all 
select 2, 'LCD' 
union all 
select 2, 'Plasma' 
union all 
select 1, 'Portable Electronic' 
union all 
select 6, 'MP3 Players' 
union all 
select 7, 'Flash' 
union all 
select 6, 'CD Player' 
union all 
select 6, 'Two Way Radios' 

;WITH CTE (id,id_parent,name_product,LEVEL,SORTKEY)AS 
(
    SELECT id, id_parent, name_product, 1, CAST(name_product AS VARBINARY(MAX)) 
    FROM @tab where id_parent is null -- Starts with the first level 

    UNION ALL 

    SELECT t.id, t.id_parent, t.name_product, C.LEVEL + 1, CAST(C.SORTKEY + CAST(t.name_product AS VARBINARY(MAX)) AS VARBINARY(MAX)) 
    FROM @tab t INNER JOIN CTE C 
    ON t.id_parent = C.id 
) 

select * from cte order by SORTKEY 

韩国社交协会

+0

如果我只能订购一个特定的级别,它的确定。 – Onaiggac 2012-08-21 20:15:05

+0

更改最终陈述中的order by从而包含LEVEL列,例如'order by LEVEL,SORTKEY' – 2013-06-24 15:54:21

+1

如果我这样做,孩子们不会跟随父母 – Onaiggac 2013-06-26 18:41:53

2

这里是正确的CTE(仅适用于ASC)

;WITH CTE AS 
(
SELECT id, id_parent, name_product 
     ,HierarchicalPath = CAST('\'+CAST(name_product AS VARCHAR(MAX)) AS VARCHAR(MAX)) 
FROM @tab where id_parent is null -- Starts with the first level 

UNION ALL 

SELECT t.id, t.id_parent, t.name_product 
     ,HierarchicalPath = CAST(c.HierarchicalPath + '\'+CAST(t.name_product AS VARCHAR(MAX)) AS VARCHAR(MAX)) 
FROM @tab t INNER JOIN CTE C 
ON t.id_parent = C.id 
) 

select * from cte order by HierarchicalPath 
0

变基于@onaiggac(你可以用自己的数据: - ))

;WITH CTE (id, id_parent, name_product, LEVEL, SORTKEY) AS 
(
    SELECT id, id_parent, name_product, 1, 
     CAST(ROW_NUMBER() OVER (ORDER BY name_product) AS VARBINARY(MAX)) 
    FROM @tab where id_parent is null -- Starts with the first level 

    UNION ALL 

    SELECT t.id, t.id_parent, t.name_product, C.LEVEL + 1, 
     C.SORTKEY + CAST(ROW_NUMBER() OVER (ORDER BY t.name_product) AS VARBINARY(MAX)) 
    FROM @tab t 
    INNER JOIN CTE C ON t.id_parent = C.id 
) 

SELECT id, id_parent, REPLICATE(' ', LEVEL - 1) + name_product, LEVEL, SORTKEY FROM CTE ORDER BY SORTKEY 

这里的诀窍是使用

ROW_NUMBER() OVER (ORDER BY name_product) 

做“内”排序。作为@onaiggac,这是然后在二进制varbinary(max)

CAST(ROW_NUMBER() OVER (ORDER BY name_product) AS VARBINARY(MAX)) 

被然后递归additioned组成...

C.SORTKEY + CAST(ROW_NUMBER() OVER (ORDER BY t.name_product) AS VARBINARY(MAX)) 

注意ROW_NUMBER()将返回bigint ......你可以将其转换为int它铸造VARBINARY(MAX),像

CAST(CAST(ROW_NUMBER() OVER (ORDER BY name_product) AS INT) AS VARBINARY(MAX)) 

,如果你真的想之前......我不认为这是necess ary除非你的树是真的深。