层次结构中的类别级别

问题描述 投票:0回答:1

具有一个脚本来查找类别列表的层次结构。但是,我需要知道该级别的深度才能找到所有相应的类别。因此,我的问题是有一种更好的方法来重写代码,以便可以将其深入到最低级别,而无需指定要深入的代码。如以下示例所示,我必须知道类别级别达到5级深度才能找到所有类别。

WITH rCTE
AS
(SELECT
        *
       ,0 AS Level
    FROM dbo.inv_category ic
    WHERE ic.Primary_org_id = 56392
    UNION ALL
    SELECT
        t.*
       ,r.Level + 1 AS Level
    FROM dbo.inv_category t
    INNER JOIN rCTE r
        ON t.Parent_id = r.Category_id)
SELECT DISTINCT
    c1.Parent_id
   ,c1.Category_id
   ,c1.Category
   ,c2.Category
   ,c2.Category_id
   ,c2.Parent_id
   ,c3.Category
   ,c3.Category_id
   ,c3.Parent_id
   ,c4.Category
   ,c4.Category_id
   ,c4.Parent_id
   ,c5.Category
   ,c5.Category_id
   ,c5.Parent_id
FROM rCTE c1
LEFT OUTER JOIN rCTE c2
    ON c1.Category_id = c2.Parent_id
LEFT OUTER JOIN rCTE c3
    ON c2.Category_id = c3.Parent_id
LEFT OUTER JOIN rCTE c4
    ON c3.Category_id = c4.Parent_id
LEFT OUTER JOIN rCTE c5
    ON c4.Category_id = c5.Parent_id
WHERE c1.Parent_id = 0
ORDER BY c1.Category, c2.Category
sql sql-server tsql join recursive-query
1个回答
0
投票

您的问题是,您希望父类别位于不同的列中,这会使任务更加复杂。

一种缩短查询并避免多个联接的选项使用条件聚合:

with rcte as (...)
select
    max(case when level = 0 then parent_id   end) parent_id_0,
    max(case when level = 0 then category_id end) category_id_0,
    max(case when level = 0 then category    end) category_0,
    max(case when level = 1 then parent_id   end) parent_id_1,
    max(case when level = 1 then category_id end) category_id_1,
    max(case when level = 1 then category    end) category_1,   
    ...
from rcte

您可以添加更多的条件表达式三元组,以根据需要管理尽可能多的最大级别;当产品的实际层次结构用尽时,以下各列将为空。

另一个选择是字符串聚合。这会为每个原始列生成一个唯一列,所有值都按照它们在层次结构中出现的顺序进行串联:

with rcte as (...)
select
    string_agg(parent_id,      ' > ') within group(order by level) parent_ids,
    string_agg(category_id_id, ' > ') within group(order by level) category_ids,
    string_agg(category,       ' > ') within group(order by level) categories
from rcte
© www.soinside.com 2019 - 2024. All rights reserved.