MySQL通过自定义函数实现递归查询父级ID或者子级ID

背 景:

在MySQL中如果是有限的层次,比如我们事先如果可以确定这个树的最大深度, 那么所有节点为根的树的深度均不会超过树的最大深度,则我们可以直接通过left join来实现。

但很多时候我们是无法控制或者是知道树的深度的。这时就需要在MySQL中用存储过程(函数)来实现或者在程序中使用递归来实现。本文讨论在MySQL中使用函数来实现的方法:

一、环境准备

1、建表

CREATE TABLE `table_name` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `status` int(255) NULL DEFAULT NULL,
 `pid` int(11) NULL DEFAULT NULL,
 PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

2、插入数据

INSERT INTO `table_name` VALUES (1, 12, 0);
INSERT INTO `table_name` VALUES (2, 4, 1);
INSERT INTO `table_name` VALUES (3, 8, 2);
INSERT INTO `table_name` VALUES (4, 16, 3);
INSERT INTO `table_name` VALUES (5, 32, 3);
INSERT INTO `table_name` VALUES (6, 64, 3);
INSERT INTO `table_name` VALUES (7, 128, 6);
INSERT INTO `table_name` VALUES (8, 256, 7);
INSERT INTO `table_name` VALUES (9, 512, 8);
INSERT INTO `table_name` VALUES (10, 1024, 9);
INSERT INTO `table_name` VALUES (11, 2048, 10);

二、MySQL函数的编写

1、查询当前节点的所有父级节点

delimiter //
CREATE FUNCTION `getParentList`(root_id BIGINT)
   RETURNS VARCHAR(1000)
   BEGIN
     DECLARE k INT DEFAULT 0;
     DECLARE fid INT DEFAULT 1;
     DECLARE str VARCHAR(1000) DEFAULT '$';
     WHILE rootId > 0 DO
       SET fid=(SELECT pid FROM table_name WHERE root_id=id);
       IF fid > 0 THEN
         SET str = concat(str,',',fid);
         SET root_id = fid;
       ELSE
         SET root_id=fid;
       END IF;
   END WHILE;
   RETURN str;
 END //
 delimiter ;

2、查询当前节点的所有子节点

delimiter //
CREATE FUNCTION `getChildList`(root_id BIGINT)
  RETURNS VARCHAR(1000)
  BEGIN
   DECLARE str VARCHAR(1000) ;
   DECLARE cid VARCHAR(1000) ;
   DECLARE k INT DEFAULT 0;
   SET str = '$';
   SET cid = CAST(root_id AS CHAR);12    WHILE cid IS NOT NULL DO
        IF k > 0 THEN
         SET str = CONCAT(str,',',cid);
        END IF;
        SELECT GROUP_CONCAT(id) INTO cid FROM table_name WHERE FIND_IN_SET(pid,cid)>0;
        SET k = k + 1;
   END WHILE;
   RETURN str;
END //
delimiter ;

三、测试

1、获取当前节点的所有父级

SELECT getParentList(10);

2、获取当前节点的所有字节

SELECT getChildList(3);

总结

以上所述是小编给大家介绍的MySQL通过自定义函数实现递归查询父级ID或者子级ID,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • mysql建立自定义函数的问题

    创建函数时问题马上出现: ERROR 1418 (HY000): This routine has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable) 在mysql在线文档中找到解决方案,网址为:

  • MySQL递归查询树状表的子节点、父节点具体实现

    简介:mysql5.0.94版本,该版本以及较高级的版本(5.5.6等等)尚未支持循环递归查询,和sqlserver.oracle相比,mysql难于在树状表中层层遍历的子节点.本程序重点参考了下面的资料,写了两个sql存储过程,子节点查询算是照搬了,父节点查询是逆思维弄的. 表结构和表数据就不公示了,查询的表user_role,主键是id,每条记录有parentid字段(对应该记录的父节点,当然,一个父节点自然会有一个以上的子节点嘛) 复制代码 代码如下: CREATE FUNCTION `g

  • SQL如何实现MYSQL的递归查询

    众所周知,目前的mysql版本中并不支持直接的递归查询,但是通过递归到迭代转化的思路,还是可以在一句SQL内实现树的递归查询的.这个得益于Mysql允许在SQL语句内使用@变量.以下是示例代码. 创建表格 CREATE TABLE `treenodes` ( `id` int , -- 节点ID `nodename` varchar (60), -- 节点名称 `pid` int -- 节点父ID ); 插入测试数据 INSERT INTO `treenodes` (`id`, `nodenam

  • 浅谈mysql 自定义函数

    因为工作需要,要写一个mysql的自定义行数,如下 DELIMITER $$ DROP FUNCTION IF EXISTS `onlineFunction`$$ CREATE FUNCTION `onlineFunction`(rrrr VARCHAR(50)) RETURNS VARCHAR(255) BEGIN IF(rrrr='online') THEN RETURN '上线';END IF; END$$ DELIMITER ; 第一行DELIMITER 定义一个结束标识符,因为MySQ

  • MySQL 自定义函数CREATE FUNCTION示例

    mysql> mysql> delimiter $$ mysql> mysql> CREATE FUNCTION myFunction -> (in_string VARCHAR(255), -> in_find_str VARCHAR(20), -> in_repl_str VARCHAR(20)) -> -> RETURNS VARCHAR(255) -> BEGIN -> DECLARE l_new_string VARCHAR(25

  • 深入mysql创建自定义函数与存储过程的详解

    一 创建自定义函数在使用mysql的过程中,mysql自带的函数可能不能完成我们的业务需求,这时就需要自定义函数,例如笔者在开发过程中遇到下面这个问题:mysql表结构如下 复制代码 代码如下: DROP TABLE IF EXISTS `test`;CREATE TABLE `test` (  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  `pic` varchar(50) NOT NULL,  `hashcode` varchar(16) N

  • MySQL中文汉字转拼音的自定义函数和使用实例(首字的首字母)

    fristPinyin : 此函数是将一个中文字符串的第一个汉字转成拼音字母 (例如:"中国人"->Z) 复制代码 代码如下: CREATE FUNCTION `fristPinyin`(P_NAME VARCHAR(255)) RETURNS varchar(255) CHARSET utf8BEGIN    DECLARE V_RETURN VARCHAR(255);    SET V_RETURN = ELT(INTERVAL(CONV(HEX(left(CONVERT(P

  • Mysql中实现提取字符串中的数字的自定义函数分享

    因需要在mysql的数据表中某一字符串中的字段提取出数字,在网上找了一通,终于找到了一个可用的mysql函数,可以有效的从字符串中提取出数字. 该mysql提取出字符串中的数字函数如下: 复制代码 代码如下: CREATE FUNCTION GetNum (Varstring varchar(50)) RETURNS varchar(30) BEGIN DECLARE v_length INT DEFAULT 0; DECLARE v_Tmp varchar(50) default ''; se

  • 关于MySQL的存储函数(自定义函数)的定义和使用方法详解

    存储函数 什么是存储函数: 封装一段sql代码,完成一种特定的功能,返回结果. 存储函数的语法: create function 函数([函数参数[,-.]]) Returns 返回类型 Begin If( Return (返回的数据) Else Return (返回的数据) end if; end; 例如: create function count_news(hits int) returns int 与存储过程返回参数不同的是存储函数在定义时没用直接声明哪个变量是返回参数,而只是使用了re

  • MySQL自定义函数简单用法示例

    本文实例讲述了MySQL自定义函数用法.分享给大家供大家参考,具体如下: 先来一个简单的,创建一个函数将'2009-06-23 00:00:00'这样格式的datetime时间转化为'2009年6月23日0时0分0秒'这样的格式: DELIMITER $$ DROP FUNCTION IF EXISTS `sp_test`.`getdate`$$ CREATE FUNCTION `sp_test`.`getdate`(gdate datetime) RETURNS varchar(255) BE

  • Mysql树形递归查询的实现方法

    前言 对于数据库中的树形结构数据,如部门表,有时候,我们需要知道某部门的所有下属部分或者某部分的所有上级部门,这时候就需要用到mysql的递归查询 最近在做项目迁移,Oracle版本的迁到Mysql版本,遇到有些oracle的函数,mysql并没有,所以就只好想自定义函数或者找到替换函数的方法进行改造. Oracle递归查询 oracle实现递归查询的话,就可以使用start with ... connect by connect by递归查询基本语法是: select 1 from 表格 st

随机推荐