日期:2014-05-16 浏览次数:20821 次
CREATE TABLE `node` ( `id` bigint(20) NOT NULL auto_increment, `parentId` varchar(20) default NULL, `name` varchar(20) default NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB
mysql> select * from node; +----+----------+-------+ | id | parentId | name | +----+----------+-------+ | 1 | NULL | root | | 2 | 1 | two | | 3 | 1 | three | | 4 | 2 | four | | 5 | 2 | five | | 6 | 3 | six | | 7 | 3 | seven | | 8 | 4 | eight | +----+----------+-------+ 8 rows in set (0.02 sec)
CREATE PROCEDURE `selectNodePosterity`(IN startId BIGINT)
    NOT DETERMINISTIC
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN
DECLARE _id bigint DEFAULT 0;
DECLARE _path VARCHAR(255);
DECLARE _last bigint DEFAULT 0;
CREATE TEMPORARY TABLE IF NOT EXISTS `temp_table` (
  `id` bigint(20) NOT NULL auto_increment,
  `path` varchar(20) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB TYPE = HEAP;
delete from temp_table;
insert into temp_table(id, path)
        select src.id, src.id from node src where id=startId;
set _id  = startId;
set _path = startId;
WHILE _id <> 0 DO
      insert into temp_table(id, path)
             select src.id, concat(concat(_path, '/'), src.id)
             from node src where src.parentId=_id;
      set _last  = _id;
      set _id  = 0;
      select id, path into _id, _path from temp_table where id>_last limit 1;
END WHILE;
select src.*, temp_table.path from temp_table, node src where temp_table.id= src.id order by temp_table.path;
END;
mysql> call selectNodePosterity(2); +----+----------+-------+-------+ | id | parentId | name | path | +----+----------+-------+-------+ | 2 | 1 | two | 2 | | 4 | 2 | four | 2/4 | | 8 | 4 | eight | 2/4/8 | | 5 | 2 | five | 2/5 | +----+----------+-------+-------+ 4 rows in set (0.00 sec) Query OK, 0 rows affected, 2 warnings (0.02 sec)