CTE 或不用于计算二级 table 中引用的树 ID

CTE or not for counting tree id's referenced in secondary table

我有一个简单的树 table,我在其中引用了类型、sub-types(无级别限制)、品牌和模型以用于简单的库存应用程序。

数据结构如下图:(nodeIsModel为boolean字段,用于计算)

ID    parentID    label               nodeIsModel
 1     -1          Root                   0  
 2     1           IT                     0
 3     2           Desktops               0
 4     3           Hewlett-Packard        0 
 5     4           HP Z240                1
 6     4           H97M-PLUS              1
 7     2           Laptops                0
 8     7           DELL                   0
 9     8           G3 3579                1

等等。

这个 table(显示在 Delphi 下的 DBTreeView 中)给我这样的东西:

ID     Label
1      Root
2        |_IT
3        |__Desktops
4        |___Hewlett-Packard
5        |____HP Z240
6        |____H97M-PLUS
7        |__Laptops
8        |___DELL
9        |____G3 3579

这个table是参考table,用户可以在其中挑选和分配一个设备,一组类型,sub-types,品牌和型号。

装备保存在另一个table(data_items),并通过所选型号的id(树结构的最低层)链接到之前的table。

例如,我的台式电脑将保存为:

itemID    itemLabel         typeID
  1       RSI-HP-DESK-01      5

因为它是 HP Z240 工作站并且在树 table 中被引用为 ID 5。

从这个 typeID 开始,我有一个 CTE 查询,它爬上树从 child ID 中找到所有 parents,这没问题。

我的问题如下:

我希望在显示 DBTreeView 时有一列显示:

还有

等等...

例如,如果我们在数据库中有 2 台 HP Z240 工作站和 1 台 DELL G3 笔记本电脑,TreeView 将如下所示:

ID     Label                    NB
1      Root
2        |_IT                   3
3        |__Desktops            2
4        |___Hewlett-Packard    2
5        |____HP Z240           1
6        |____H97M-PLUS         1
7        |__Laptops             1
8        |___DELL               1
9        |____G3 3579           1

基于树 table 中的 "nodeIsModel" 布尔字段,我尝试了查询,有些查询带有 CTE,有些则没有,但我对 JOIN 和 sub-queries 感到困惑,还收到有关以下内容的错误消息:

aggregate queries not being allowed in CTE

如有任何建议,我们将不胜感激。


根据 Dale K 的要求,这里是递归查询,从 child ID 开始给我所有 parents :

这个查询有效。我正在寻找一个新查询,该查询将加入树 table 和项目 table,给出分配给树每个级别项目的模型计数

WITH CTE AS (
SELECT
    ID,
    parentID,
    label,
    CAST (nodeLevel AS INTEGER) AS LEVEL
FROM
    dico_TBM
WHERE
    ID = :lookupID
UNION ALL
    SELECT
        r.ID,
        t.parentID,
        t.label,
        LEVEL - 1
    FROM
        dico_TBM t
    INNER JOIN CTE r ON t.ID = r.parentID
) SELECT DISTINCT
    r.ID,
    r.parentID,
    r.label,
    LEVEL
FROM
    CTE r
WHERE
    LEVEL > 0
ORDER BY
    LEVEL

(nodeLevel 是一个整数,给出了我在问题中没有提及的树中节点的级别,认为它没有意义,并且 :lookupID 是起始 child 节点的 ID I作为参数传递给我的查询)

使用 nodeIsModel = 1 作为 recursive cte 的锚定成员,并从那里开始提升级别

with
rcte as
(
    select  *
    from    dico_TBM
    where   nodeIsModel = 1

    union all

    select  d.*
    from    rcte r
            inner join dico_TBM d   on  r.parnetID  = d.ID
)
select  ID, label, count(*) as NB
from    rcte
group by ID, label
order by ID

下面是一种可以帮助您解决问题的方法。以下是我的类似设置

下面的查询为我们提供了资源树中每个级别的资源计数。

;with CTE1 AS (
  SELECT r.id, r.label, r.parentID, count(*) AS ItemCount 
    FROM resourcetree r 
    JOIN items i ON (r.id = i.resourceID) 
   GROUP BY r.id, r.label, r.parentID
), 
CTE2 AS (
  SELECT r.id, r.label, r.parentID, SUM(cte1.itemCount) AS ItemCount, 0 AS sumFlag 
    FROM resourceTree r 
    JOIN CTE1 ON (r.id = cte1.parentID) 
   GROUP BY r.id, r.label, r.parentID
  UNION ALL
  SELECT r.id, r.label, r.parentID, cte2.ItemCount AS ItemCount, 1 AS sumFlag 
    FROM resourceTree r 
    JOIN cte2 ON (r.id = cte2.parentID)
)
SELECT r.id, 
       r.label, 
       COALESCE(c2_1.ItemCount, c2_0.ItemCount, cte1.ItemCount, 0) AS ItemCount 
  FROM resourceTree r 
  LEFT JOIN cte1 ON r.id = cte1.id 
  LEFT JOIN cte2 c2_0 ON (r.id = c2_0.id AND c2_0.sumFlag = 0)
  LEFT JOIN (SELECT id, label, SUM(ItemCount) AS ItemCount 
               FROM CTE2 
              WHERE sumFlag = 1 
              GROUP BY id, label) c2_1 ON r.id = c2_1.id

下面是我得到的结果。希望能帮助到你。 谢谢

PS:我不必使用 'NodeIsModel' 标志