繁体   English   中英

过滤掉分层数据

[英]Filtering out hierarchical data

我需要帮助解决我在处理分层数据时遇到的问题。

维护分层数据的表的架构:

分类表:

|   ID  |   Label | 

映射表:

|   ID  |   QualifierID     | ItemID    | ParentID  |

第 1 步:编写一个简单的自连接查询来转换上面的映射:

WITH category_masterlist AS (
  SELECT    id,
            label
  FROM Category
)

select id, id as itemid, label, NULL as parentId from [Category] where categoryLevel = 1
UNION
select itemid as id, itemId, (select label from category_masterlist where id = cm.itemid) Label, parentId
from [CategoryMapping] cm

第二步:使用公用表表达式写了一个自连接查询返回映射数据如下:

WITH CategoryCTE(ParentID, ID, Label, CategoryLevel) AS
(
    SELECT ParentID, ItemID, Label, 0 AS CategoryLevel
    FROM [view_TreeviewCategoryMapping]
    WHERE ParentID IS NULL
    UNION ALL
    SELECT e.ParentID, e.ItemID, e.Label, CategoryLevel + 1
    FROM [view_TreeviewCategoryMapping] AS e
        INNER JOIN CategoryCTE AS d
        ON e.ParentID = d.ID
)
SELECT distinct ParentID, ID, Label, CategoryLevel
FROM CategoryCTE

|   ID  |   Label           | ParentID  | CategoryLevel |
--------------------------------------------------------------------------------                                
|   90  |   Satellite       |   NULL    |   0       |
|   91  |   Concrete        |   NULL    |   0       |
|   92  |   ETC             |   NULL    |   0       |
|   93  |   Chisel          |   NULL    |   0       |
|   94  |   Steel           |   NULL    |   0       |
|   96  |   Wood            |   NULL    |   0       |
|   97  |   MIC Systems     |   90      |   1       |
|   97  |   MIC Systems     |   91      |   1       |
|   99  |   Foundations     |   91      |   1       |
|   100 |   Down Systems    |   91      |   1       |
|   101 |   Side Systems    |   91      |   1       |
|   102 |   Systems         |   91      |   1       |
|   98  |   DWG             |   92      |   1       |   
|   97  |   MIC Systems     |   93      |   1       |
|   97  |   MIC Systems     |   94      |   1       |
|   99  |   Foundations     |   94      |   1       |   
|   100 |   Down Systems    |   94      |   1       |
|   101 |   Side Systems    |   94      |   1       |
|   102 |   Systems         |   94      |   1       |
|   97  |   MIC Systems     |   95      |   1       |
|   98  |   DWG             |   95      |   1       |
|   102 |   Systems         |   95      |   1       |
|   103 |   Project Management| 95      |   1       |   
|   104 |   Software        |   95      |   1       |
|   99  |   Foundations     |   96      |   1       |
|   119 |   Fronts          |   97      |   2       |
|   121 |   Technology      |   98      |   2       |
|   112 |   Root Systems    |   98      |   2       |   
|   112 |   Root Systems    |   99      |   2       |
|   137 |   Closed Systems  |   112     |   3       |
|   203 |   Support         |   121     |   3       |

第 3 步:我想过滤以上结果,以便只返回完全映射的类别。 完成的映射是具有级别=3 的子级的映射。 例如,下面是我根据上述结果集寻找的内容:

|   ID  |   Label           | ParentID  | CategoryLevel |
--------------------------------------------------------------------------------

|   96  |   Wood            |   NULL    |   0       |
|   92  |   ETC             |   NULL    |   0       |
|   98  |   DWG             |   92      |   1       |
|   99  |   Foundations     |   96      |   1       |
|   121 |   Technology      |   98      |   2       |
|   112 |   Root Systems    |   98      |   2       |
|   112 |   Root Systems    |   99      |   2       |
|   137 |   Closed Systems  |   112     |   3       |
|   203 |   Support         |   121     |   3       |

第 4 步:最终,应向最终用户显示如下树视图控件:

Root
|
|---Wood
|   |---Foundations
|       |---Root Systems
|           |---Closed Systems
|
|---ETC
|   |---DWG
|       |---Technology
|           |---Support
|       |---Root Systems
|           |---Closed Systems

请注意,一个类别可以有多个父级。 例如,Root Systems 有两个父项 - DWG 和 Foundations。 我是否得到了类别和映射表的正确架构,尤其是在一个类别可以有多个父项的情况下?

如何从第 2 步到第 3 步过滤掉未完全映射的类别? 这是我无法跨越的障碍。 任何指针? 我可以在应用程序级别过滤掉它们,但我真的很想在数据库级别过滤掉它们。

我乐于接受有助于我实现目标的建议。 我还想确认我正在使用的模式是最有效的模式。

谢谢!

这是一个使用数据类型hierarchyID的工作选项

嵌套是可选的,实际上是为了说明。

例子

Declare @Top   int         = null      --<<  Sets top of Hier Try 94
 
;with cteP as (
      Select ID
            ,ParentID 
            ,Label 
            ,HierID = convert(hierarchyid,concat('/',ID,'/'))
      From   YourTable 
      Where  IsNull(@Top,-1) = case when @Top is null then isnull(ParentID ,-1) else ID end
      Union  All
      Select ID  = r.ID
            ,Pt  = r.ParentID 
            ,Label   = r.Label
            ,HierID = convert(hierarchyid,concat(p.HierID.ToString(),r.ID,'/'))
      From   YourTable r
      Join   cteP p on r.ParentID  = p.ID)
Select Lvl   = HierID.GetLevel()
      ,ID
      ,ParentID
      ,Label  = replicate('|----',HierID.GetLevel()-1) + Label  -- Nesting Optional ... For Presentation
      ,HierID_String = HierID.ToString()
 From cteP A
 Order By A.HierID

结果

在此处输入图像描述

现在如果@Top 设置为 94

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM