递归CTE和种子

时间:2017-04-04 23:55:41

标签: sql sql-server recursion common-table-expression

我有一个名为TabShop的表 - cols和数据子集是: (假设掩盖实际......)

|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 个答案:

答案 0 :(得分: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
                 );

答案 1 :(得分: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