【问题标题】:count nested tree user计算嵌套树用户
【发布时间】:2011-10-14 09:26:23
【问题描述】:
id  left_User_ID  right_User_ID  referral_Id
--  ------------  -------------  -----------
1   2             5              1
2   3             4              1
3   null          null           2

我想计算用户 1 下有多少成员。 为此,我创建了一个仅计算左侧的函数。

所以它就像 1->2->3.so 它算 2。 计算右侧也一样。

那么如何计算所有边的意思是左和右

【问题讨论】:

  • ...你已经用 SQL 标记了它,但我没有看到任何特定于 SQL 的内容(甚至,实际上,任何表明正在使用数据库的东西)...
  • 调用函数向左计数并存储答案。调用函数计算正确并存储答案。将两个答案加在一起。

标签: sql sql-server-2005 recursion


【解决方案1】:

没有对问题更具体的定义,很难提供好的帮助。但是,如果您可以计算左侧条目,那么听起来您已经完成了一半。

与其计算左侧条目,不如尝试计算两边。这个伪代码看起来像这样:

public static int leafCount(Node node) {
   if (node == null) {
       return 0;
   }

   return 1 + leafCount(node.left) + leafCount(node.right);
}

如果您使用的任何后端语言都有用于树结构的库,我希望已经提供了类似的功能。


编辑:

在揭示我们确实有一个树形表结构后,可以用 SQL 查询 -

表:

CREATE TABLE RECURSE (ID INT NOT NULL WITH DEFAULT, 
                      R_SIDE INT NOT NULL WITH DEFAULT, 
                      L_SIDE INT NOT NULL WITH DEFAULT)   

数据:

INSERT INTO RECURSE VALUES (1, 2, 5)
                           (2, 3, 4)
                           (3, 0, 0)
                           (4, 0, 0)
                           (5, 0, 0)

结果设置:

Id    R_Side    L_Side
 1    2         5
 2    3         4
 3    0         0
 4    0         0
 5    0         0

此语句将返回左右节点的计数。至少在 DB2 下,似乎有一些限制使得 left joins 难以在递归 CTE 中使用,因此您必须分别计算左侧和右侧。如果它不能完全满足您的需求,请将此作为起点。

WITH left_side (id, count) as (SELECT id, 0
                               FROM recurse
                               WHERE L_Side = 0
                               UNION ALL
                               SELECT a.id, 1 + b.count
                               FROM recurse as a
                               JOIN left_side as b
                               ON b.id = a.l_side
                               where a.l_side > 0),

     right_side (id, count) as (SELECT id, 0
                                FROM recurse
                                WHERE R_Side = 0
                                UNION ALL
                                SELECT a.id, 1 + b.count
                                FROM recurse as a
                                JOIN right_side as b
                                ON b.id = a.R_Side
                                where a.l_side > 0)

SELECT a.id, COALESCE(b.count, 0) + COALESCE(c.count, 0) as LeafCount
FROM recurse as a
LEFT JOIN right_side as b
ON b.id = a.id
LEFT JOIN left_side as c
ON clid = a.id

产量:

Id     LeafCount
 1     3
 2     2
 3     0
 4     0
 5     0

【讨论】:

  • 如何在 MS sql 2005 中实现上述概念。这是递归..但不知道如何用 CTE 实现。
【解决方案2】:

这是递归......只有在 sql 中使用 cte 才能进行递归。我使用了 MS SQL 服务器 2005 。我试试这个来计算左侧节点 这里我的表名是 LEG

  1. 创建函数left_legs(@id int)
  2. 返回 varchar(4) 作为开始
  3. DECLARE @count int set @count=0 WHILE @id !=0
  4. 开始
  5. set@id=cast((SELECT left_user_Id from Leg where id=@id)as varchar(4))
  6. 如果@id != 0
  7. 开始
  8. 设置@count =@count +'1'
  9. 结束
  10. 结束
  11. 返回@count
  12. 结束
    此函数计算左节点总数。仅在一个方向上。

【讨论】:

    【解决方案3】:
    SELECT
       Sum(
       CASE WHEN left_user_ID is null THEN 0 ELSE 1 END +
       CASE WHEN right_user_ID is null THEN 0 ELSE 1 END
       )
    FROM
       Table
    WHERE
       referral_Id = 1
    

    【讨论】:

    • 但我想得到总数。节点 1 下的节点数。也就是 4。仍然无法理解,如何通过 sql2005 中的 CTE 实现
    猜你喜欢
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 2014-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-02
    相关资源
    最近更新 更多