2012-08-16 225 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除非你的樹是真的深。