`
wenjie12201
  • 浏览: 148305 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论
  • luoxun11: 其实这个问题的本质是用##包围变量的时候ibatis会采用St ...
    iBATIS #和$

转mysql递归层次查询

 
阅读更多
在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点。但shi,在MySQL的目前版本中还没有对应的函数!!! 
 
换句话来说,想要用mysql实现递归查询,根本做不到!!! 
可是经过我数天茶不思饭不想的刻苦琢磨,终于想到了一个合理的,适用于mysql和其他sql的解决方案。
  www.2cto.com  
方案一出,就秋风扫落叶之势,席卷整个dao层~~~所到之处,所有问题迎刃而解,让所有问题都不再为问题 都成为了我这个函数的炮灰而已。。。 
 
话不多说待我把解决方法仔细道来~~~~~ 
 
下面是sql脚本,想要运行一下 把下边的粘贴复制下来,做一个treenodes.sq直接运行便是。。。 
/* 
Navicat MySQL Data Transfer 
 
Source Server         : mysql_demo3 
Source Server Version : 50521 
Source Host           : localhost:3306 
Source Database       : test 
 
Target Server Type    : MYSQL 
Target Server Version : 50521 
File Encoding         : 65001 
  www.2cto.com  
Date: 2012-09-02 21:16:03 
*/ 
 
SET FOREIGN_KEY_CHECKS=0; 
 
-- ---------------------------- 
-- Table structure for `treenodes` 
-- ---------------------------- 
DROP TABLE IF EXISTS `treenodes`; 
CREATE TABLE `treenodes` ( 
  `id` int(11) NOT NULL, 
  `nodename` varchar(20) DEFAULT NULL, 
  `pid` int(11) DEFAULT NULL, 
  PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 
 
-- ---------------------------- 
-- Records of treenodes 
-- ---------------------------- 
INSERT INTO `treenodes` VALUES ('1', 'A', '0'); 
INSERT INTO `treenodes` VALUES ('2', 'B', '1'); 
INSERT INTO `treenodes` VALUES ('3', 'C', '1'); 
INSERT INTO `treenodes` VALUES ('4', 'D', '2'); 
INSERT INTO `treenodes` VALUES ('5', 'E', '2'); 
INSERT INTO `treenodes` VALUES ('6', 'F', '3'); 
INSERT INTO `treenodes` VALUES ('7', 'G', '6'); 
INSERT INTO `treenodes` VALUES ('8', 'H', '0'); 
INSERT INTO `treenodes` VALUES ('9', 'I', '8'); 
INSERT INTO `treenodes` VALUES ('10', 'J', '8'); 
INSERT INTO `treenodes` VALUES ('11', 'K', '8'); 
INSERT INTO `treenodes` VALUES ('12', 'L', '9'); 
INSERT INTO `treenodes` VALUES ('13', 'M', '9'); 
INSERT INTO `treenodes` VALUES ('14', 'N', '12'); 
INSERT INTO `treenodes` VALUES ('15', 'O', '12'); 
INSERT INTO `treenodes` VALUES ('16', 'P', '15'); 
INSERT INTO `treenodes` VALUES ('17', 'Q', '15'); 
  www.2cto.com  
--------------------------------------------------- 
上边是sql脚本,在执行select * 之后显示的结果集如下所示: 
mysql> select * from treenodes; 
+----+----------+------+ 
| id | nodename | pid  | 
+----+----------+------+ 
|  1 | A        |    0 | 
|  2 | B        |    1 | 
|  3 | C        |    1 | 
|  4 | D        |    2 | 
|  5 | E        |    2 | 
|  6 | F        |    3 | 
|  7 | G        |    6 | 
|  8 | H        |    0 | 
|  9 | I        |    8 | 
| 10 | J        |    8 | 
| 11 | K        |    8 | 
| 12 | L        |    9 | 
| 13 | M        |    9 | 
| 14 | N        |   12 | 
| 15 | O        |   12 | 
| 16 | P        |   15 | 
| 17 | Q        |   15 | 
+----+----------+------+ 
17 rows in set (0.00 sec) 
 
树形图如下 
1:A 
  +-- 2:B 
  |    +-- 4:D 
  |    +-- 5:E 
  +-- 3:C 
       +-- 6:F 
            +-- 7:G 
8:H 
  +-- 9:I 
  |    +-- 12:L 
  |    |    +--14:N 
  |    |    +--15:O 
  |    |        +--16:P 
  |    |        +--17:Q 
  |    +-- 13:M 
  +-- 10:J 
  +-- 11:K   
-------------------------------------------- 
 
如果给你一个这样的table,让你查询根节点为1下的所有节点记录(注意也包括根节点),,肿麽办????? 
可能有不少人想到connect by 函数,但是我灰常遗憾的告诉你,咱这儿是mysql!!! 
 
好,客观您勒上眼,,我的解决办法是 
利用函数来得到所有子节点号。 
 
闲话少续,看我的解决方法 
创建一个function getChildLst, 得到一个由所有子节点号组成的字符串.  
 
mysql> delimiter // 
mysql> 
mysql> CREATE FUNCTION `getChildLst`(rootId INT) 
    -> RETURNS varchar(1000) 
    -> BEGIN 
    ->   DECLARE sTemp VARCHAR(1000); 
    ->   DECLARE sTempChd VARCHAR(1000); 
    -> 
    ->   SET sTemp = '$'; 
    ->   SET sTempChd =cast(rootId as CHAR); 
    -> 
    ->   WHILE sTempChd is not null DO 
    ->     SET sTemp = concat(sTemp,',',sTempChd); 
    ->     SELECT group_concat(id) INTO sTempChd FROM treeNodes where FIND_IN_SET(pid,sTempChd)>0; 
    ->   END WHILE; 
    ->   RETURN sTemp; 
    -> END 
    -> // 
Query OK, 0 rows affected (0.00 sec) 
 
mysql> 
mysql> delimiter ; 
  www.2cto.com  
使用我们直接利用find_in_set函数配合这个getChildlst来查找 
 
mysql> select getChildLst(1); 
+-----------------+ 
| getChildLst(1)  | 
+-----------------+ 
| $,1,2,3,4,5,6,7 | 
+-----------------+ 
1 row in set (0.00 sec) 
 
mysql> select * from treeNodes 
    -> where FIND_IN_SET(id, getChildLst(1)); 
+----+----------+------+ 
| id | nodename | pid  | 
+----+----------+------+ 
|  1 | A        |    0 | 
|  2 | B        |    1 | 
|  3 | C        |    1 | 
|  4 | D        |    2 | 
|  5 | E        |    2 | 
|  6 | F        |    3 | 
|  7 | G        |    6 | 
+----+----------+------+ 
7 rows in set (0.01 sec) 
 
mysql> select * from treeNodes 
    -> where FIND_IN_SET(id, getChildLst(3)); 
+----+----------+------+ 
| id | nodename | pid  | 
+----+----------+------+ 
|  3 | C        |    1 | 
|  6 | F        |    3 | 
|  7 | G        |    6 | 
+----+----------+------+ 
3 rows in set (0.01 sec) 
 
-------------------------------------------- 
只要按我的做,百发百中弹无虚发,遇到问题万变不离其宗直接粘贴复制就是。。。 
 
补充:
 
还可以做嵌套查询: 
select id,pid from treeNodes where id in( 
     select id from treeNodes where FIND_IN_SET(id, getChildLst(3)) 
); 
子查询的结果集是 
  www.2cto.com  
+--------+ 
id 
---- 
+-------+ 
然后经过外层查询就是 
 
id  pid 
3   1 
6   3 
6   6 
--------- 
好了 Perfect
分享到:
评论

相关推荐

    多级数据-Mysql中的递归层次查询(父子查询).doc

    多级数据-Mysql中的递归层次查询(父子查询).doc

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

    在MySQL中如果是有限的层次,比如我们事先如果可以确定这个树的最大深度, 那么所有节点为根的树的深度均不会超过树的最大深度,则我们可以直接通过left join来实现。 但很多时候我们是无法控制或者是知道树的深度的...

    MySQL实现树状所有子节点查询的方法

    本文实例讲述了MySQL实现树状所有子节点查询的方法。分享给大家供大家参考,具体如下: 在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点。但很遗憾,...

    PHP使用递归生成文章树

    数据库好设计,无非用id,fatherid来进行归类,fatherid代表父类是那篇文章的id,id是文章的唯一id,层次不限,可以是两层,可以是三层。fatherid为0的表示顶层文章。 php代码,主要是递归 function category_tree($...

    中国地区代码,单表树状结构sql脚本(mysql版本)

    因本人需要1张单表递归出所有数据树状层次,才有了这个脚步。供广大朋友节约时间,测试使用 其中简介: db:test 源数据的3张单表:province , city ,district 整合后的单表:t_china 数据量:3215条,量不大 层级...

    经典SQL脚本大全

    │ │ 8.2.2 树形数据深度排序处理示例(递归法).sql │ │ 8.2.3 查找指定节点的所有子节点的示例函数.sql │ │ 8.2.4 查找指定节点的所有父节点的示例函数.sql │ │ 8.2.5 校验插入指定结点是否导致编码循环的...

    Sqlserver2000经典脚本

    复杂交叉表1.sql │ 多栏显示.sql │ 日期+星期+时间.sql │ 格式化报表.sql │ 横转竖-1.sql │ 横转竖-字段名.sql │ 横转竖-生成字段名.sql │ 横转竖.sql │ 行列互换的复杂...

    Ubuntu权威指南(2/2)

    5.2.4 递归地列出文件 112 5.3 显示文件内容 113 5.3.1 使用cat命令显示文件 113 5.3.2 使用more命令分页显示 文件 113 5.3.3 使用less命令分页显示 文件 114 5.3.4 使用head命令显示文件 前几行内容 115 5.3.5 使用...

    Ubuntu权威指南(1/2)

    5.2.4 递归地列出文件 112 5.3 显示文件内容 113 5.3.1 使用cat命令显示文件 113 5.3.2 使用more命令分页显示 文件 113 5.3.3 使用less命令分页显示 文件 114 5.3.4 使用head命令显示文件 前几行内容 115 5.3.5 使用...

    史上最全韩顺平传智播客PHP就业班视频,10月份全集

    9-27 5 函数的调用 递归及深入使用 9-27 6 一维?榧笆樵谀诖嬷械拇嬖谛问? 9-27 7 常用数组的属性及使用方法 9-28 1课程回顾 9-28 2 二维数组的定义使用 数组排序 9-28 3 顺序查找 二分查找 9-28 4 javascript...

    (全)传智播客PHP就业班视频完整课程

    9-27 5 函数的调用 递归及深入使用 9-27 6 一维?榧笆樵谀诖嬷械拇嬖谛问? 9-27 7 常用数组的属性及使用方法 9-28 1课程回顾 9-28 2 二维数组的定义使用 数组排序 9-28 3 顺序查找 二分查找 9-28 4 javascript...

    史上最全传智播客PHP就业班视频课,8月份视频

    9-27 5 函数的调用 递归及深入使用 9-27 6 一维?榧笆樵谀诖嬷械拇嬖谛问? 9-27 7 常用数组的属性及使用方法 9-28 1课程回顾 9-28 2 二维数组的定义使用 数组排序 9-28 3 顺序查找 二分查找 9-28 4 javascript...

    韩顺平PHP JS JQUERY 所有视频下载种子 货真价实

    9-27 5 函数的调用 递归及深入使用 9-27 6 一维?榧笆樵谀诖嬷械拇嬖谛问? 9-27 7 常用数组的属性及使用方法 9-28 1课程回顾 9-28 2 二维数组的定义使用 数组排序 9-28 3 顺序查找 二分查找 9-28 4 javascript...

    史上最全韩顺平传智播客PHP就业班视频,9月份全集

    9-27 5 函数的调用 递归及深入使用 9-27 6 一维?榧笆樵谀诖嬷械拇嬖谛问? 9-27 7 常用数组的属性及使用方法 9-28 1课程回顾 9-28 2 二维数组的定义使用 数组排序 9-28 3 顺序查找 二分查找 9-28 4 javascript...

    SQL培训第一期

    //递归查询父节点 select t.* from g_organ t start with t.organcode = '080' connect by t.parentcode = prior t.organcode; //递归查询子节点 1.8.7 union 和 union all 1.8.7.1 语法 select * from dual union ...

    疯狂JAVA讲义

    5.2.4 递归方法 121 5.2.5 方法重载 123 学生提问:为什么方法的返回值类型不能用于区分重载的方法? 124 5.3 成员变量和局部变量 124 5.3.1 成员变量和局部变量 125 5.3.2 成员变量的初始化和内存中的运行机制...

Global site tag (gtag.js) - Google Analytics