So I\'m trying to create a comment system in which you can reply to comments that are already replies (allowing you to create theoretically infinite threads of replies). I want
You might find this method helpful which involves a single call to a non-recursive stored procedure.
Full script can be found here : http://pastie.org/1259785
Hope it helps :)
Example stored procedure call:
call comments_hier(1);
Example php script:
query(sprintf("call comments_hier(%d)", 3));
while($row = $result->fetch_assoc()){
...
}
$result->close();
$conn->close();
?>
SQL script:
drop table if exists comments;
create table comments
(
comment_id int unsigned not null auto_increment primary key,
subject varchar(255) not null,
parent_comment_id int unsigned null,
key (parent_comment_id)
)engine = innodb;
insert into comments (subject, parent_comment_id) values
('Comment 1',null),
('Comment 1-1',1),
('Comment 1-2',1),
('Comment 1-2-1',3),
('Comment 1-2-2',3),
('Comment 1-2-2-1',5),
('Comment 1-2-2-2',5),
('Comment 1-2-2-2-1',7);
delimiter ;
drop procedure if exists comments_hier;
delimiter #
create procedure comments_hier
(
in p_comment_id int unsigned
)
begin
declare v_done tinyint unsigned default 0;
declare v_depth smallint unsigned default 0;
create temporary table hier(
parent_comment_id smallint unsigned,
comment_id smallint unsigned,
depth smallint unsigned default 0
)engine = memory;
insert into hier select parent_comment_id, comment_id, v_depth from comments where comment_id = p_comment_id;
/* http://dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html */
create temporary table tmp engine=memory select * from hier;
while not v_done do
if exists( select 1 from comments c inner join hier on c.parent_comment_id = hier.comment_id and hier.depth = v_depth) then
insert into hier
select c.parent_comment_id, c.comment_id, v_depth + 1 from comments c
inner join tmp on c.parent_comment_id = tmp.comment_id and tmp.depth = v_depth;
set v_depth = v_depth + 1;
truncate table tmp;
insert into tmp select * from hier where depth = v_depth;
else
set v_done = 1;
end if;
end while;
select
c.comment_id,
c.subject,
p.comment_id as parent_comment_id,
p.subject as parent_subject,
hier.depth
from
hier
inner join comments c on hier.comment_id = c.comment_id
left outer join comments p on hier.parent_comment_id = p.comment_id
order by
hier.depth, hier.comment_id;
drop temporary table if exists hier;
drop temporary table if exists tmp;
end #
delimiter ;
call comments_hier(1);
call comments_hier(5);