zoukankan      html  css  js  c++  java
  • mysql递归层次查询

    mysql递归层次查询

     
    最近在做一个从oracle数据库到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 
    --------- 
    转自:http://www.2cto.com/database/201209/152513.html
  • 相关阅读:
    Chat Application using Web services in C#(转载)
    Asynchronous Method Invocation(转载)
    Passing Data between Windows Forms(转载)
    Fill in PDF Form Fields using the Open Source iTextSharp Dynamic Link Library(转载)
    The ShutDown Alarm(转载)
    使用blowery.Web.HttpCompress.dll对aspx压缩
    C# Voice and Tone Alert Generator(转载)
    Compress Folders with C# and the SharpZipLib(转载)
    Ubuntu 12.10 修改窗口按键布局(buttom_layout)到右边
    同步CM9源代码
  • 原文地址:https://www.cnblogs.com/yuan951/p/6429441.html
Copyright © 2011-2022 走看看