mysql树状查询(转)

转自https://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/
--创建表
drop table  if exists t_hierarchy;
CREATE TABLE t_hierarchy (
        id int(10) unsigned NOT NULL AUTO_INCREMENT,
        parent int(10) unsigned NOT NULL,
        PRIMARY KEY (id),
        KEY ix_hierarchy_parent (parent, id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


--创建存储过程插入数据
DROP PROCEDURE if exists prc_fill_hierarchy;
DELIMITER $$
CREATE PROCEDURE prc_fill_hierarchy (level INT, fill INT)
BEGIN
        DECLARE _level INT;
        DECLARE _fill INT;
        INSERT
        INTO    t_hierarchy (id, parent)
        VALUES  (1, 0);
        SET _fill = 0;
        WHILE _fill < fill DO
                INSERT
                INTO    t_hierarchy (parent)
                VALUES  (1);
                SET _fill = _fill + 1;
        END WHILE;
        SET _fill = 1;
        SET _level = 0;
        WHILE _level < level DO
                INSERT
                INTO    t_hierarchy (parent)
                SELECT  hn.id
                FROM    t_hierarchy ho, t_hierarchy hn
                WHERE   ho.parent = 1
                        AND hn.id > _fill;
                SET _level = _level + 1;
                SET _fill = _fill + POWER(fill, _level);
        END WHILE;
END
$$
DELIMITER ;


--插入数据
START TRANSACTION;
CALL prc_fill_hierarchy(3, 2);
COMMIT;


--创建生成树的函数
DELIMITER $$
CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_id(value INT) RETURNS INT
NOT DETERMINISTIC
READS SQL DATA
BEGIN
        DECLARE _id INT;
        DECLARE _parent INT;
        DECLARE _next INT;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL;


        SET _parent = @id;
        SET _id = -1;


        IF @id IS NULL THEN
                RETURN NULL;
        END IF;


        LOOP
                SELECT  MIN(id)
                INTO    @id
                FROM    t_hierarchy
                WHERE   parent = _parent
                        AND id > _id;
                IF @id IS NOT NULL OR _parent = @start_with THEN
                        SET @level = @level + 1;
                        RETURN @id;
                END IF;
                SET @level := @level - 1;
                SELECT  id, parent
                INTO    _id, _parent
                FROM    t_hierarchy
                WHERE   id = _parent;
        END LOOP;       
END
$$
DELIMITER ;


--生成tree的查询
SELECT  CONCAT(REPEAT('--->', level - 1), CAST(hi.id AS CHAR)) AS treeitem, parent, level
FROM    (
        SELECT  hierarchy_connect_by_parent_eq_prior_id(id) AS id, @level AS level
        FROM    (
                SELECT  @start_with := 0,
                        @id := @start_with,
                        @level := 0
                ) vars, t_hierarchy
        WHERE   @id IS NOT NULL
        ) ho
JOIN    t_hierarchy hi
ON      hi.id = ho.id

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10972173/viewspace-2143075/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10972173/viewspace-2143075/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 树状查询指的是一种特殊的查询方式,主要用于处理树形结构的数据。通常在数据库中保存树形结构数据时,我们采用的是一个中包含一个主键和一个指向它父节点的外键来示树形结构,这样就可以使用基本的 SQL 查询语句来读取数据。但是,如果我们需要查询树形结构的数据路径,或者需要按照特定的层级关系来显示树形结构,这时候基本的 SQL 查询语句显然无法满足我们的需求。 为了解决这个问题,MySQL 提供了一些专门的树状查询语句,比如使用 WITH RECURSIVE 关键字实现递归查询。具体来说,我们可以通过 WITH RECURSIVE 关键字生成一个递归的子查询,该子查询包含一个递归的 WITH 子句和一个 SELECT 查询。WITH 子句用于定义递归的终止条件和递归查询的初始结果集,而 SELECT 查询则用于不断地将结果集扩展到下一级目录,直到满足终止条件为止。 例如,以下是一个查询包含三个字段 (id、name 和 parent_id) 的树形结构数据 test_table 中,包含指定节点路径的所有父节点: WITH RECURSIVE recursive_table AS ( SELECT id, name, parent_id FROM test_table WHERE id = 5 UNION ALL SELECT t.id, t.name, t.parent_id FROM recursive_table AS r, test_table AS t WHERE t.id = r.parent_id ) SELECT id, name, parent_id FROM recursive_table; 在上述查询中,我们首先从 test_table 数据中查找 id=5 的节点,然后创建一个递归的 recursive_table 子查询,从结果集中取出 id、name 和 parent_id 三个字段的值。然后我们使用 UNION ALL 语句将这个初始结果集与一条递归查询语句连接起来,该语句会不断递归地将结果集扩展到下一层目录,直到没有更多的父节点为止。最后,我们在主查询中选取 id、name 和 parent_id 三个字段的值,以显示包含路径的所有父节点。 需要注意的是,使用树状查询语句可能会对数据库服务器的性能产生影响,特别是在处理大型树形结构时。因此,在使用树状查询语句时,我们应该尽可能地限制递归查询的深度和查询条件的复杂度,以避免对数据库性能的不良影响。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值