我有用户表,其中包含以下字段
用户
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/