MySQL中实现递归查询

 

对于数据库中的树形结构数据,如部门表,有时候,我们需要知道某部门的所有下属部分或者某部分的所有上级部门,这时候就需要用到mysql的递归查询

1、创建表

DROP TABLE IF EXISTS `t_areainfo`;
CREATE TABLE `t_areainfo` (
`id` int(11) NOT '0' AUTO_INCREMENT,
`level` int(11) DEFAULT '0',
`name` varchar(255) DEFAULT '0',
`parentId` int(11) DEFAULT '0',
`status` int(11) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8;

2、初始数据

INSERT INTO `t_areainfo` VALUES ('1', '0', '中国', '0', '0');
INSERT INTO `t_areainfo` VALUES ('2', '0', '华北区', '1', '0');
INSERT INTO `t_areainfo` VALUES ('3', '0', '华南区', '1', '0');
INSERT INTO `t_areainfo` VALUES ('4', '0', '北京', '2', '0');
INSERT INTO `t_areainfo` VALUES ('5', '0', '海淀区', '4', '0');
INSERT INTO `t_areainfo` VALUES ('6', '0', '丰台区', '4', '0');
INSERT INTO `t_areainfo` VALUES ('7', '0', '朝阳区', '4', '0');
INSERT INTO `t_areainfo` VALUES ('8', '0', '北京XX区1', '4', '0');
INSERT INTO `t_areainfo` VALUES ('9', '0', '北京XX区2', '4', '0');
INSERT INTO `t_areainfo` VALUES ('10', '0', '北京XX区3', '4', '0');
INSERT INTO `t_areainfo` VALUES ('11', '0', '北京XX区4', '4', '0');
INSERT INTO `t_areainfo` VALUES ('12', '0', '北京XX区5', '4', '0');
INSERT INTO `t_areainfo` VALUES ('13', '0', '北京XX区6', '4', '0');
INSERT INTO `t_areainfo` VALUES ('14', '0', '北京XX区7', '4', '0');
INSERT INTO `t_areainfo` VALUES ('15', '0', '北京XX区8', '4', '0');
INSERT INTO `t_areainfo` VALUES ('16', '0', '北京XX区9', '4', '0');
INSERT INTO `t_areainfo` VALUES ('17', '0', '北京XX区10', '4', '0');
INSERT INTO `t_areainfo` VALUES ('18', '0', '北京XX区11', '4', '0');
INSERT INTO `t_areainfo` VALUES ('19', '0', '北京XX区12', '4', '0');
INSERT INTO `t_areainfo` VALUES ('20', '0', '北京XX区13', '4', '0');
INSERT INTO `t_areainfo` VALUES ('21', '0', '北京XX区14', '4', '0');
INSERT INTO `t_areainfo` VALUES ('22', '0', '北京XX区15', '4', '0');
INSERT INTO `t_areainfo` VALUES ('23', '0', '北京XX区16', '4', '0');
INSERT INTO `t_areainfo` VALUES ('24', '0', '北京XX区17', '4', '0');
INSERT INTO `t_areainfo` VALUES ('25', '0', '北京XX区18', '4', '0');
INSERT INTO `t_areainfo` VALUES ('26', '0', '北京XX区19', '4', '0');
INSERT INTO `t_areainfo` VALUES ('27', '0', '北京XX区1', '4', '0');
INSERT INTO `t_areainfo` VALUES ('28', '0', '北京XX区2', '4', '0');
INSERT INTO `t_areainfo` VALUES ('29', '0', '北京XX区3', '4', '0');
INSERT INTO `t_areainfo` VALUES ('30', '0', '北京XX区4', '4', '0');
INSERT INTO `t_areainfo` VALUES ('31', '0', '北京XX区5', '4', '0');
INSERT INTO `t_areainfo` VALUES ('32', '0', '北京XX区6', '4', '0');
INSERT INTO `t_areainfo` VALUES ('33', '0', '北京XX区7', '4', '0');
INSERT INTO `t_areainfo` VALUES ('34', '0', '北京XX区8', '4', '0');
INSERT INTO `t_areainfo` VALUES ('35', '0', '北京XX区9', '4', '0');
INSERT INTO `t_areainfo` VALUES ('36', '0', '北京XX区10', '4', '0');
INSERT INTO `t_areainfo` VALUES ('37', '0', '北京XX区11', '4', '0');
INSERT INTO `t_areainfo` VALUES ('38', '0', '北京XX区12', '4', '0');
INSERT INTO `t_areainfo` VALUES ('39', '0', '北京XX区13', '4', '0');
INSERT INTO `t_areainfo` VALUES ('40', '0', '北京XX区14', '4', '0');
INSERT INTO `t_areainfo` VALUES ('41', '0', '北京XX区15', '4', '0');
INSERT INTO `t_areainfo` VALUES ('42', '0', '北京XX区16', '4', '0');
INSERT INTO `t_areainfo` VALUES ('43', '0', '北京XX区17', '4', '0');
INSERT INTO `t_areainfo` VALUES ('44', '0', '北京XX区18', '4', '0');
INSERT INTO `t_areainfo` VALUES ('45', '0', '北京XX区19', '4', '0');
INSERT INTO `t_areainfo` VALUES ('46', '0', 'xx省1', '1', '0');
INSERT INTO `t_areainfo` VALUES ('47', '0', 'xx省2', '1', '0');
INSERT INTO `t_areainfo` VALUES ('48', '0', 'xx省3', '1', '0');
INSERT INTO `t_areainfo` VALUES ('49', '0', 'xx省4', '1', '0');
INSERT INTO `t_areainfo` VALUES ('50', '0', 'xx省5', '1', '0');
INSERT INTO `t_areainfo` VALUES ('51', '0', 'xx省6', '1', '0');
INSERT INTO `t_areainfo` VALUES ('52', '0', 'xx省7', '1', '0');
INSERT INTO `t_areainfo` VALUES ('53', '0', 'xx省8', '1', '0');
INSERT INTO `t_areainfo` VALUES ('54', '0', 'xx省9', '1', '0');
INSERT INTO `t_areainfo` VALUES ('55', '0', 'xx省10', '1', '0');
INSERT INTO `t_areainfo` VALUES ('56', '0', 'xx省11', '1', '0');
INSERT INTO `t_areainfo` VALUES ('57', '0', 'xx省12', '1', '0');
INSERT INTO `t_areainfo` VALUES ('58', '0', 'xx省13', '1', '0');
INSERT INTO `t_areainfo` VALUES ('59', '0', 'xx省14', '1', '0');
INSERT INTO `t_areainfo` VALUES ('60', '0', 'xx省15', '1', '0');
INSERT INTO `t_areainfo` VALUES ('61', '0', 'xx省16', '1', '0');
INSERT INTO `t_areainfo` VALUES ('62', '0', 'xx省17', '1', '0');
INSERT INTO `t_areainfo` VALUES ('63', '0', 'xx省18', '1', '0');
INSERT INTO `t_areainfo` VALUES ('64', '0', 'xx省19', '1', '0');

3、向下递归

利用find_in_set()函数和group_concat()函数实现递归查询:

DROP FUNCTION IF EXISTS queryChildrenAreaInfo;
DELIMITER ;;
CREATE FUNCTION queryChildrenAreaInfo(areaId INT)
RETURNS VARCHAR(4000)
BEGIN
DECLARE sTemp VARCHAR(4000);
DECLARE sTempChd VARCHAR(4000); SET sTemp='$';
SET sTempChd = CAST(areaId AS CHAR); WHILE sTempChd IS NOT NULL DO
SET sTemp= CONCAT(sTemp,',',sTempChd);
SELECT GROUP_CONCAT(id) INTO sTempChd FROM t_areainfo WHERE FIND_IN_SET(parentId,sTempChd)>0;
END WHILE;
RETURN sTemp;
END
;;
DELIMITER ;

4、调用方式

SELECT queryChildrenAreaInfo(1);

查询id为"4"下面的所有节点

SELECT * FROM t_areainfo WHERE FIND_IN_SET(id,queryChildrenAreaInfo(4));

5、向上递归

DROP FUNCTION IF EXISTS queryChildrenAreaInfo1;
DELIMITER;;
CREATE FUNCTION queryChildrenAreaInfo1(areaId INT)
RETURNS VARCHAR(4000)
BEGIN
DECLARE sTemp VARCHAR(4000);
DECLARE sTempChd VARCHAR(4000); SET sTemp='$';
SET sTempChd = CAST(areaId AS CHAR);
SET sTemp = CONCAT(sTemp,',',sTempChd); SELECT parentId INTO sTempChd FROM t_areainfo WHERE id = sTempChd;
WHILE sTempChd <> 0 DO
SET sTemp = CONCAT(sTemp,',',sTempChd);
SELECT parentId INTO sTempChd FROM t_areainfo WHERE id = sTempChd;
END WHILE;
RETURN sTemp;
END
;;
DELIMITER ;

6、调用方式

查询id为"7"的节点的所有上级节点:

SELECT * from t_areainfo where FIND_IN_SET(id,queryChildrenAreaInfo1(7));

自定义条件递归

CREATE DEFINER=`app`@`%` FUNCTION `queryChildrenAreaInfo`(areaId INT,areaType INT) RETURNS varchar(4000) CHARSET utf8mb4
BEGIN
DECLARE sTemp VARCHAR(4000);
DECLARE sTempChd VARCHAR(4000); SET sTemp = '$';
SET sTempChd = cast(areaId as char);
-- 查询传入areaId及其以下所有子节点
WHILE sTempChd is not NULL DO
SET sTemp = CONCAT(sTemp,',',sTempChd);
-- 根据区域父ID和区域类型
SELECT group_concat(area_id) INTO sTempChd FROM d_area_define where AREA_TYPE =areaType and FIND_IN_SET(p_area_id,sTempChd)>0;
END WHILE;
return sTemp;
END

优化后sql

-- 调用方式
select queryChildrenAreaInfo(0,2);
-- 业务调用
-- select * from sla_map_plotting t where FIND_IN_SET(area_id, queryChildrenAreaInfo(0,2)); --此方法查询较慢
select * from sla_map_plotting,(select queryChildrenAreaInfo(28,4) ids) t where FIND_IN_SET(area_id, ids);

mysql 递归的更多相关文章

  1. MYSQL 递归操作

    MYSQL 递归? ===================== 表: t_node node_id int node_name varchar2(45) parent_id int       级, ...

  2. MySQL递归的替代方案

    类似查出某个机构下所有的子机构,可用递归的方式实现.但MySQL不支持递归,可以考虑用如下的方式来实现递归调用. 第一种,临时表方式,使用函数每次查出子机构,再可以和其他表联查. 第二种,新建一张表, ...

  3. mysql递归

    sql Server可以用with as 语法,mysql没有这个功能,只能用别的方式了,目前的mysql版本中并不支持直接的递归查询,但是通过递归到迭代转化的思路,还是可以在一句SQL内实现树的递归 ...

  4. mysql 递归查找菜单节点的所有子节点

    背景                                                                                                   ...

  5. Mysql 递归获取多重数组数据

    多重数据 $data ,获取顶级下的所有下级id $data array:3 [▼ 0 => array:7 [▼ "id" => 1 "created_at ...

  6. mysql 递归查找所有子节点

    select dept_id from ( select t1.dept_id,t1.parent_id, if(find_in_set(parent_id, @pids) > 0, @pids ...

  7. mysql 实现oracle start with connect by递归

    在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点.但很遗憾,在MySQL的目前版本中还没有对应的功能. ...

  8. mysql中递归树状结构<转>

    在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点.但很遗憾,在MySQL的目前版本中还没有对应的功能. ...

  9. MySQL中进行树状所有子节点的查询

    在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点.但很遗憾,在MySQL的目前版本中还没有对应的功能. ...

  10. oracle和mysql几点差异对比

    Oracle与mysql差异性总结 之前有个项目是用oracle数据库进行开发,需要把数据库改成mysql,遇到了一些地方需要注意的,就简单记了下来. 备注: 再把oracle转成mysql的时候,表 ...

随机推荐

  1. MySQL 5.7升级8.0过程(详解)

    记一次MySQL 5.7升级8.0的详细过程,聊聊我的思路,希望可以帮助大家. 以一个例子为切入点 一.升级背景 为什么要升级到MySQL8.0?大概多久进行一次? 大家可以参考下图记录的各个版本的发 ...

  2. jwt刷新token

    前一段时间讲过了springboot+jwt的整合,但是因为一些原因(个人比较懒)并没有更新关于token的刷新问题,今天跟别人闲聊,聊到了关于业务中token的刷新方式,所以在这里我把我知道的一些点 ...

  3. fabric2.2学习笔记1

    fabric2.2学习笔记1 20201303张奕博 2023年1月9日 hyperledger fabric 结构分析 每个Server作用: AdminServer:控制该节点的命运,可以删除该节 ...

  4. [Python.Unix和Linux系统管理指南]书籍

    Python.Unix和Linux系统管理指南书籍下载地址 提取码:eqf4 内容简介  · · · · · · <Python UNIX和Linux系统管理指南>介绍了Python语言如 ...

  5. linux创建数据库以及数据库用户密码

    登录linux服务器成功后: 登录mysql: mysql -uroot -p 输入密码:xxxx 创建数据库: create database test 创建用户及密码: create user ' ...

  6. 基础篇之Markdown基础语法

    标题 1. # + 空格 + 标题名字 → 一级标题 2. ## + 空格 + 标题名字 → 二级标题 3. ### + 空格 + 标题名字 → 三级标题 ...... 6.###### + 空格 + ...

  7. JS 将伪数组转换成数组

    在 JS 中,伪数组 是非常常见的,它也叫 类数组.伪数组可能会给 JS 初学者带来一点困扰. 本文将详细讲解 什么是伪数组,以及分别在 ES5 和 ES6 中将伪数组转换成真正的数组 . 什么是伪数 ...

  8. pandas常用方法之read_excel详解

    前期准备 准备测试数据如下: fl_path = r"C:\Users\Desktop\test.xlsx" dic = { 'num': ['001', '002', '003' ...

  9. C/C++:printf 函数格式化输出,用法详细记录

    printf ( print format )函数是接触C/C++之后接触的第一个函数,它的功能除了输出hello world外,更重要的是进行格式化输出,比如输出整数的%d,输出小数的%f,%lf ...

  10. 解决通配符的匹配很全面, 但无法找到元素 'aop:config' 的声明

    这是因为在applicationContext.xml文件中没有添加对应的地址 http://www.springframework.org/schema/aop http://www.springf ...