-1

我有一个存储父、左子和右子信息的表。我如何计算属于该父母的孩子的数量?

例如我的表结构是:

parent  left  right
--------------------
 1        2     3
 3        4     5
 4        8     9
 5        10    11
 2        6     7
 9        12    null

如何计算任何父节点的子节点数。
例如,4 包含以下分层子节点 - 8,9,12,因此子节点数为 3。3
包含以下子节点 -> 4,5,10,11,8,9,12,因此子节点总数为 7。

如何使用 SQL 查询来实现这一点?

4

1 回答 1

0
create table mytable
(   parent int not null,
    cleft int null,
    cright int null
)
insert into mytable (parent,cleft,cright) values (1,2,3);
insert into mytable (parent,cleft,cright) values (2,6,7);
insert into mytable (parent,cleft,cright) values (3,4,5);
insert into mytable (parent,cleft,cright) values (4,8,9);
insert into mytable (parent,cleft,cright) values (5,10,11);
insert into mytable (parent,cleft,cright) values (6,null,null);
insert into mytable (parent,cleft,cright) values (7,null,null);
insert into mytable (parent,cleft,cright) values (8,13,null);
insert into mytable (parent,cleft,cright) values (9,12,null);
insert into mytable (parent,cleft,cright) values (10,null,null);
insert into mytable (parent,cleft,cright) values (12,null,null);
insert into mytable (parent,cleft,cright) values (13,null,17);
insert into mytable (parent,cleft,cright) values (17,null,null);


DELIMITER $$
CREATE procedure GetChildCount (IN parentID INT)
DETERMINISTIC
BEGIN
    declare ch int;
    declare this_left int;
    declare this_right int;
    declare bContinue boolean;
    declare count_needs_scan int;

    create temporary table asdf999 (node_id int,processed int);
    -- insert into asdf999 (node_id,processed) values (1,0);
    -- update asdf999 set processed=1;

    SET ch = parentID;
    set bContinue=true;
    while bContinue DO
        -- at this point you are sitting at a ch (anywhere in hierarchy)
        -- as you are looping and getting/using children

        -- save non-null children references: -----------------------------
        select cleft into this_left from mytable where parent=ch;
        if !isnull(this_left) then
            insert asdf999 (node_id,processed) select this_left,0;
        end if;

        select cright into this_right from mytable where parent=ch;
        if !isnull(this_right) then
            insert asdf999 (node_id,processed) select this_right,0;
        end if;
        -- -----------------------------------------------------------------
        select count(*) into count_needs_scan from asdf999 where processed=0;
        if count_needs_scan=0 then
            set bContinue=false;
        else
            select node_id into ch from asdf999 where processed=0 limit 1;
            update asdf999 set processed=1 where node_id=ch;
            -- well, it is about to be processed
        end if;
    END WHILE;
    select count(*) as the_count from asdf999;
    drop table asdf999;
END $$
DELIMITER ;

call GetChildCount(2);  -- answer is 2
call GetChildCount(4);  -- answer is 5

我可以提供一个创建动态命名表(或临时表)的版本,如果需要,可以在最后破坏它。过程中的“动态 sql / 准备语句”。这样用户就不会因为共享使用 asdf999 工作台而互相踩踏。所以这还没有准备好生产。但以上内容让您对这个概念有所了解

于 2015-05-29T15:05:32.537 回答