2017-04-04 109 views
-2

我有表名爲TabShop - 的cols和數據的一個子集是: (假設以掩蓋實際...)遞歸CTE和種子

|ShopCategory |Item   |ItemOrCategory 
|------------ |------------ |-------------- 
|Greens  |Cabbage  |item 
|Greens  |Cucumber  |item 
|Reds   |Beetroot  |item 
|Reds   |Onions  |item 
|Browns  |Potatoes  |item 
|RootVeg  |Browns  |category 
|Grocery  |Greens  |category 
|Grocery  |RootVeg  |category 
|Grocery  |Rice   |item 
|RootVeg  |Parsnip  |item 
|Vegetables |Reds   |category 

使用遞歸CTE,我需要如下顯示所有項目遍歷後...:

Category |Item 
---------- |----- 
Vegetables |Beetroot 
Vegetables |Onions 
Grocery |Rice 
Grocery |Parsnip 
Grocery |Cabbage 
Grocery |Cucumber 
Reds  |Beetroot 
Reds  |Onions 
Greens  |Cabbage 
Greens  |Cucumber 
RootVeg |Parsnip 
RootVeg |Potatoes 
Browns  |Potatoes 

請協助創建一個CTE以顯示上面...謝謝。

+2

您的示例數據似乎不符合您的要求的輸出,除非我失去了一些東西。例如馬鈴薯是棕色的,棕色是根莖,根莖是雜貨......所以馬鈴薯不會在雜貨類別下面? – ZLK

回答

0

你可以使用遞歸CTE這樣的:

DECLARE @SampleDAta as TABLE (ShopCategory varchar(20) ,Item varchar(20),ItemOrCategory varchar(20)) 

INSERT INTO @SampleDAta VALUES ('Greens'  ,'Cabbage'  ,'item') 
INSERT INTO @SampleDAta VALUES ('Greens'  ,'Cucumber'  ,'item') 
INSERT INTO @SampleDAta VALUES ('Reds'   ,'Beetroot'  ,'item') 
INSERT INTO @SampleDAta VALUES ('Reds'   ,'Onions'  ,'item') 
INSERT INTO @SampleDAta VALUES ('Browns'  ,'Potatoes'  ,'item') 
INSERT INTO @SampleDAta VALUES ('RootVeg'  ,'Browns'  ,'category') 
INSERT INTO @SampleDAta VALUES ('Grocery'  ,'Greens'  ,'category') 
INSERT INTO @SampleDAta VALUES ('Grocery'  ,'RootVeg'  ,'category') 
INSERT INTO @SampleDAta VALUES ('Grocery'  ,'Rice'   ,'item') 
INSERT INTO @SampleDAta VALUES ('RootVeg'  ,'Parsnip'  ,'item') 
INSERT INTO @SampleDAta VALUES ('Vegetables' ,'Reds'   ,'category') 

;WITH temp AS 
(
    SELECT sd.ShopCategory, sd.Item, sd.ItemOrCategory 
    FROM @SampleDAta sd 
    WHERE sd.ItemOrCategory = 'item' 
    UNION ALL 
    SELECT sd.ShopCategory, t.Item, sd.ItemOrCategory 
    FROM @SampleDAta sd 
    INNER JOIN temp t ON t.ShopCategory = sd.Item 
) 
SELECT t.ShopCategory, t.Item FROM temp t 
Order By t.ShopCategory 
OPTION (MAXRECURSION 0) 

你期望的結果是不正確的。它不包括Grocery - Potatoes

+0

真棒,謝謝你的答案。 – Sandiyan

0

遞歸CTE如下面應該工作:

with cte as (
     select s.shopcategory, s.item, 1 as lev 
     from tabshop s 
     where not exists (select 1 
         from tabshop s2 
         where s2.item = s.shopcategory 
         ) 
     union all 
     select cte.shopcategory, s.item, lev + 1 
     from tabshop s join 
      cte 
      on s.shopcategory = cte.item 
    ) 
select * 
from cte 
where not exists (select 1 
        from tabshop s2 
        where s2.shopcategory = cte.item 
       );