在sql中使用递归搜索的子查询

时间:2014-10-06 11:57:06

标签: sql subquery case

表Item.ItemCategory:

问题-1:

CategoryID类别BelongsTo

35电子0

39数码相机35
  40 DSLR镜头39
  41佳能40

问题-2:

  Concatenate 'category 'column such as Electronics->Digital Camera-> DSLR Lens-> Canon when 41->categoryid is passed

查询:

Select IC.Category,IC.CategoryID,IC.BelongsTo,
                        case when IC.BelongsTo !=0 then
                        (select IC2.BelongsTo from Item.ItemCategory IC2 where IC2.CategoryID=IC.BelongsTo) 
                        else 
                        IC.CategoryID
                        end as CategoryGroup                                                          
                        from Sales.SalesBillMaster SBM
                        inner join Sales.SalesBillChild SBC on SBC.CBranchId = SBM.BranchID and SBC.CBillNumber= SBM.BillNumber
                        inner join Masters.TaxMaster TM on TM.TaxId=SBC.TaxID 
                        inner join Item.ItemMaster IM on IM.ItemID=SBC.ItemID
                        inner join Item.ItemCategory IC ON IC.CategoryID=IM.ItemCategoryID
                        where  SBM.DeleteFlag<>1 and SBC.DeleteFlag <> 1 and dbo.GetDateToCompare(SBM.BillDate) BETWEEN dbo.GetDateToCompare('10/06/2014') AND dbo.GetDateToCompare('10/06/2014') AND SBM.BranchID in (SELECT * FROM Masters.udf_string_to_table ('1,2',',')) and IC.CategoryID in(41)      

输出错误:

CategoryID类别BelongsTo CategoryGroup

41佳能40 39

预期产出:

CategoryID类别BelongsTo CategoryGroup

41           Canon         40                35

说明:

    As 'canon' belongs to categoryid-40(DSLR Lens) then 40 belongs to categoryid-39
   (Digital camera) then 39 belongs to categoryid-35(Electronics) so if 'canon'
   comes means i need values of 35 in CategoryGroup case column..
   canon categoryid 41->40->39->35 which means we have go bottom to top to find 
   root category..  the root category belongsto column always will be assigned as 0..

2 个答案:

答案 0 :(得分:0)

检查此行

(select IC2.BelongsTo from Item.ItemCategory IC2 where IC2.CategoryID=IC.BelongsTo)

因为这永远不会为您提供预期的输出。 您BelongsTo的{​​{1}}值为ItemCategory。在这种情况下,您的CategoryID = BelongsToBelongsTo,因此查询会为您提供40行,其值为BelongsTo,在这种情况下为:

CategoryId = 40

您确实应该首先编写一个递归查询,选择特定类别的父级,然后返回它的值。

修改有关递归查询的帮助请转到here

实现您所需要的最简单方法: 简单的方法:

40 DSLR Lens 39 <-- this value

希望这能让您深入了解CTE /递归CTE。请记住,这不是最有效的方式(至少我认为是这样)。

答案 1 :(得分:0)

回答问题1:

WITH abcd(BelongsTo, CategoryId, Category, Level)AS(
SELECT BelongsTo, CategoryId, Category, 0 AS Level FROM ItemCategory WHERE CategoryId = 41
UNION ALL
SELECT ii.BelongsTo, ii.CategoryId, ii.Category, Level + 1 AS Level FROM ItemCategory ii, abcd aa WHERE ii.CategoryId = aa.BelongsTo)SELECT 
BelongsTo, 
CategoryId, 
Category,(SELECT CategoryId FROM abcd WHERE Level = (SELECT max(Level) FROM abcd)) AS CategoryGroup FROM 
ItemCategory  WHERE CategoryId = 41;

回答问题-2:

            with category as(select categoryid,category,
                    CAST((category) AS VARCHAR(1000)) AS 'Cg' from item.itemcategory where CategoryId = 41
                    union all
                    select I.categoryid,I.category,
                    CAST((c.Cg + '->' + CAST((I.category) AS VARCHAR(1000))) AS VARCHAR(1000)) AS 'Cg'                              from item.itemcategory I
                    inner join category c on c.categoryid=i.belongsto 
                    and I.CategoryID in(41)
                    )                        
                    select cg  from item.itemcategory c inner join category k on c.categoryid=k.categoryid