Mysql程序,循环返回分层数据

标签 mysql stored-procedures procedure

我有用户表,其中包含以下字段

用户 user_id INT
parent_user_id INT
一个INT
b INT

我想创建返回给定parent_user_id的所有子节点的过程

这是我所拥有的

DROP PROCEDURE IF EXISTS read_user_tree;
DELIMITER //
CREATE PROCEDURE read_user_tree(IN input_data INT) NOT DETERMINISTIC
BEGIN

    SET @id = input_data;
    myLoop: loop
        SELECT `user_id`, `a`, `b` into @id, @a, @b FROM `user` WHERE parent_user_id = @id;
        if  
            @id is null
        then
            leave myLoop; 
        end if;
           SELECT `user_id`, `a`, `b` FROM `user` WHERE user_id = @a
           union
           SELECT `user_id`, `a`, `b` FROM `user` WHERE user_id = @b;

    end loop myLoop; 

END //
DELIMITER ;

当我运行这个过程时,我得到的是随机结果而不是树数据

编辑1:

我尝试将数据添加到临时表中,但出现错误“#1172 - 结果包含多行”

DROP PROCEDURE IF EXISTS read_user_tree;
DELIMITER //
CREATE PROCEDURE read_user_tree(IN input_data INT) NOT DETERMINISTIC
BEGIN

    SET @id = input_data;

 CREATE TEMPORARY TABLE tmp_user_data (
    `user_id` int(11) NOT NULL, 
    `a` int(11) NOT NULL, 
    `b` int(11) NOT NULL, 
    `parent_user_id` int(11) NOT NULL
  ) ENGINE=MEMORY DEFAULT CHARSET=latin1;

  myLoop: loop
        SELECT `user_id`, `a`, `b` into @id, @a, @b FROM `user` WHERE parent_user_id = @id;
        if
            @id is null
        then
            leave myLoop;
        end if;
        insert into tmp_user_data (`user_id`, `a`, `b`, `parent_user_id`)
        SELECT `user_id`, `a`, `b`, `parent_user_id` FROM `user` WHERE user_id = @a;
        insert into tmp_user_data (`user_id`, `a`, `b`, `parent_user_id`)
        SELECT `user_id`, `a`, `b`, `parent_user_id` FROM `user` WHERE user_id = @b;

    end loop myLoop; 

    select * from tmp_user_data;

END //
 DELIMITER ;

编辑2:

添加第二个临时表用作队列后,我得到了想要的结果

DROP PROCEDURE IF EXISTS read_user_tree;
DELIMITER //
CREATE PROCEDURE read_user_tree(IN input_data INT) NOT DETERMINISTIC
BEGIN

    SET @id = input_data;

 CREATE TEMPORARY TABLE tmp_user_data (
    `user_id` int(11) NOT NULL, 
    `a` int(11) , 
    `b` int(11) , 
    `parent_user_id` int(11)
  ) ENGINE=MEMORY DEFAULT CHARSET=latin1;

 CREATE TEMPORARY TABLE tmp_user_level (
    `user_id` int(11) NOT NULL
  ) ENGINE=MEMORY DEFAULT CHARSET=latin1;


  insert into tmp_user_level select user_id from `user` WHERE parent_user_id = @id;
  myLoop: loop
        select user_id into @cur from tmp_user_level LIMIT 1;
        select FOUND_ROWS() into @cnt;
        if
            @cnt = 0
        then
            leave myLoop;
        end if;
        SELECT `user_id`, `a`, `b`, `parent_user_id` into @user_id, @a, @b, @parent_user_id FROM `user` WHERE user_id = @cur; 
        insert into tmp_user_data (`user_id`, `a`, `b`, `parent_user_id`) values( @user_id, @a, @b, @parent_user_id);
        delete from tmp_user_level where user_id = @cur;
         if
           @a is not null
        then
            insert into tmp_user_level (user_id) values(@a);
        end if;

        if
           @b is not null
        then
            insert into tmp_user_level (user_id) values(@b);
        end if;

    end loop myLoop; 
    select * from tmp_user_data;


END //
 DELIMITER ;

最佳答案

全凭内存,如有错误请见谅。但是您可能需要创建一个临时表并在循环内插入查询结果。我以前就是这么做的。

CREATE TEMPORARY TABLE results LIKE `user`;
...
<loop>
...
INSERT INTO results (user, a, b)
   SELECT ... UNION SELECT ... ;
...
</loop>
SELECT * FROM results;
DROP TEMPORARY TABLE results;

您必须有创建临时表的权限;

关于Mysql程序,循环返回分层数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46456611/

相关文章:

php - 选择列中的最后一个条目与其他列不同

MYSQL 检索一个表中在另一个表中出现最多的行

mysql - laravel 5.1 有多安全?

sql-server - 从 SQL 存储过程导出文本文件

mysql - 过程中的光标不返回任何值

php - 如何使用 php 和我的 sql 检索根节点的所有节点

sql - 选择字段设置为空或为空的所有记录

plsql - PL/SQL 在选择中为每个结果插入 1 行

forms - 在 Delphi 中销毁一个窗体并显示另一个窗体的正确方法

asp.net - 如何在SqlDataSource中为存储过程指定参数值