mysql对树进行递归查询

在进行数据库移植的过程中,遇到了对树进行递归查询的问题。

在SQL server 中,很容易实现。如下图:

WITH Tree
AS (SELECT T1.F_EnergyItemCode FROM T_DT_EnergyItemDict AS T1 WHERE T1.F_EnergyItemCode = @EnergyItemCode
UNION ALL
SELECT T2.F_EnergyItemCode FROM T_DT_EnergyItemDict AS T2 INNER JOIN Tree ON T2.F_ParentItemCode = Tree.F_EnergyItemCode)

而mysql 不支持with as。

实现方法:

建立一个存储过程:

CREATE DEFINER=`root`@`localhost` PROCEDURE `spg_GetChildLst`(IN `p_id` varchar(100),IN `p_col_name` varchar(100),IN `p_col_p_name` varchar(100),IN `p_t_name` varchar(100),OUT `p_RetVal` varchar(1000))
BEGIN
  /**
   递归查找从属项,输入参数分别为具体的父项ID,查找的ID列名,父项的ID列名,和表名。输出一个所有ID的字符串。
  **/
    DECLARE sTemp VARCHAR(1000);
  DECLARE sTempChd VARCHAR(1000);
  declare v_sql varchar(500);    -- 需要执行的SQL语句

  SET sTemp = ‘$‘;
  SET sTempChd =cast(p_id as CHAR);

  set v_sql= concat(‘SELECT group_concat(‘,p_col_name,‘ ) INTO @sTempChd FROM ‘,p_t_name,‘ where FIND_IN_SET(‘,p_col_p_name,‘,@sTempChd)>0‘);

  set @v_sql=v_sql;   -- 注意很重要,将连成成的字符串赋值给一个变量(可以之前没有定义,但要以@开头)

       WHILE sTempChd is not null DO
         SET sTemp = concat(sTemp,‘,‘,sTempChd);
         SET @sTempChd=sTempChd;
         prepare stmt from @v_sql;  -- 预处理需要执行的动态SQL,其中stmt是一个变量
         EXECUTE stmt;  -- 执行SQL语句
         deallocate prepare stmt;     -- 释放掉预处理段
         SET sTempChd=@sTempChd;

         -- SELECT group_concat(F_EnergyItemCode) INTO sTempChd FROM T_DT_EnergyItemDict where FIND_IN_SET(F_ParentItemCode,sTempChd)>0;
      END WHILE;

    SET p_RetVal=sTemp;

END

为什么要建立存储过程那?因为我们项目很多业务都涉及到树这种从属关系,所以抽象出来,每个表使用递归的时候,直接输入一些字段名和ID和表名即可。

而函数是不支持执行动态SQL的。

然后在实际项目中,调用这个存储过程即可。、

例如:

CALL spg_GetChildLst(@EnergyItemCode,‘F_EnergyItemCode‘,‘F_ParentItemCode‘,‘T_DT_EnergyItemDict‘,@stmp);

            INSERT INTO TmpP01 (F_Id, F_Type) SELECT F_EnergyItemCode, 0 FROM  ( SELECT F_EnergyItemCode FROM T_DT_EnergyItemDict
      WHERE FIND_IN_SET(F_EnergyItemCode, @stmp)
          ) AS T;

总结:关键点就是mysql动态执行SQL,并且通过@变量名的形式获取返回值。

然后就是FIND_IN_SET()这个函数。

时间: 2024-08-30 03:09:06

mysql对树进行递归查询的相关文章

MySQL知识树-支持的数据类型

本篇学习笔记的主要内容: 介绍MySQL支持的各种数据类型(常用),并讲解其主要特点.   MySQL支持多种数据类型,主要包括数值类型.日期和时间类型.字符串类型. 数值类型 MySQL的数值类型包括整数类型.浮点数类型.定点数类型.位类型. 整数类型 MySQL支持的整数类型有tinyint.smallint.mediumint.int.bigint(范围从小到大). zerofill 我们在定义整数类型时可以在类型名称后面的小括号内指定显示宽度,例如int(5),当插入的数值宽度小于5位时

[MySQL]B+树索引

[MySQL]B+树索引 摘要:[MySQL]B+树索引B+树是一种经典的数据结构,由平衡树和二叉查找树结合产生,它是为磁盘或其它直接存取辅助设备而设计的一种平衡查找树,在B+树中,所有的记录节点都是按键值大小顺序存放在同一层的叶节点中,叶节... SyntaxHighlighter.all(); ... B+树是一种经典的数据结构,由平衡树和二叉查找树结合产生,它是为磁盘或其它直接存取辅助设备而设计的一种平衡查找树,在B+树中,所有的记录节点都是按键值大小顺序存放在同一层的叶节点中,叶节点间用

mysql B+树索引简述

一,查询B+树索引的流程 B+树索引找到叶节点,再找到对应的数据页,然后将数据页加载到内存中,通过二分查找Page Directory中的槽,查找出一个粗略的目录,然后根据槽的指针指向链表中的行记录,之后在链表中依次查找. 需要注意的地方是,B+树索引不能找到具体的一条记录,而是只能找到对应的页.把页从磁盘装入到内存中,再通过Page Directory进行二分查找,同时此二分查找也可能找不到具体的行记录(有可能会找到),只是能找到一个接近的链表中的点,再从此点开始遍历链表进行查找. 二,聚簇索

MySQL知识树-查询语句

在日常的web应用开发过程中,一定会涉及到数据库方面的操作,其中查询又是占绝大部分的.我们不仅要会写查询,最好能系统的学习下与查询相关的知识点,这篇文章我们就来一起看看MySQL查询知识相关的树是什么样的. MySQL查询知识树: 一.查询的种类 二.查询的原理 三.查询的应用场景 四.查询的效率比较 五.如何进行查询优化 六.与查询相关的知识扩展 一.查询的种类 MySQL的查询可以分为内连接查询.左连接查询.右连接查询.联合查询. ①内连接是通过关联表中共有的列来匹配出记录,查询出来的数据是

MySQL B+树索引和哈希索引的区别

导读 在MySQL里常用的索引数据结构有B+树索引和哈希索引两种,我们来看下这两种索引数据结构的区别及其不同的应用建议. 二者区别 备注:先说下,在MySQL文档里,实际上是把B+树索引写成了BTREE,例如像下面这样的写法: CREATE TABLE t(aid int unsigned not null auto_increment,userid int unsigned not null default 0,username varchar(20) not null default ‘’,

分针网——每日分享:MySQL实现树的遍历

更多文章:www.f-z.cn 经常在一个表中有父子关系的两个字段,比如empno与manager,这种结构中需要用到树的遍历.在Oracle 中可以使用connect by简单解决问题,参见http://blog.csdn.net/wzy0623/archive/2007/06/18/1656345.aspx,但MySQL 5.1中还不支持(据说已纳入to do中),要自己写过程或函数来实现. 一.建立测试表和数据 [c-sharp] view plain copy DROP TABLE IF

字符串的公共前缀对Mysql B+树查询影响回溯分析

年前项目组接微信公众号. 上线之后,跟微信相关的用cid列的查询会话的SQL变慢了几十倍!思考这个问题思考了非常久.从出现以来一直是我心头的一个结.cid这一列是建了索引的,普通的cid列更新都没问题,为何仅仅有微信的有问题?同样的前缀又是怎样影响索引的? 分析过程 1.explain下微信cid的查询.微信的cid会以mid-qqwanggou001为前缀插入数据 explain select * from analysis_sessions where cid = "mid-qqwanggo

MySQL B+树索引和哈希索引的区别(转 JD二面)

导读 在MySQL里常用的索引数据结构有B+树索引和哈希索引两种,我们来看下这两种索引数据结构的区别及其不同的应用建议. 二者区别 备注:先说下,在MySQL文档里,实际上是把B+树索引写成了BTREE,例如像下面这样的写法: CREATE TABLE t(aid int unsigned not null auto_increment,userid int unsigned not null default 0,username varchar(20) not null default '',

mysql 查找树状子节点函数

CREATE FUNCTION getChildList(rootId INT) RETURNS varchar(1000) BEGIN DECLARE sChildList VARCHAR(1000); DECLARE sChildTemp VARCHAR(1000); SET sChildTemp =cast(rootId as CHAR); WHILE sChildTemp is not null DO IF (sChildList is not null) THEN SET sChild