sql—在层次结构中查找类别级别

to94eoyn  于 2021-08-13  发布在  Java
关注(0)|答案(1)|浏览(349)

我有一个脚本来查找类别列表的层次结构。不过,我需要知道的深度水平,找到所有相应的类别。所以我的问题是有没有更好的方法来重写代码,这样它就可以深入到最底层,而不需要我指定要深入到什么程度。作为下面的例子,我必须知道类别级别深入到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
mftmpeh8

mftmpeh81#

您的问题是,您希望父类别位于不同的列中,这使得任务比可能的任务更复杂。
缩短查询并避免多个联接的一个选项使用条件聚合:

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

相关问题