MYSQL递归树查询的实现

2018-12-22  本文已影响0人  boskt

​    在oracle中我们可以使用connect by prior 函数来实现组织树表递归的查询,但是在mysql中却没有该方法,为了能够使用该方法我们就得自己创建函数来实现该组织树的递归查询。以下实现了2种方式来满足子节点的递归查询与父节点的递归查询。

实现子递归查询

1.单个子递归查询的实现

oracle中使用示例代码:

SELECT
   T.ID
FROM
   bas_basic_tree T CONNECT BY PRIOR T.ID = T.PID
   START WITH T.ID = #{id}

mysql中使用示例代码:

SELECT
   ID
FROM 
    bas_basic_tree T,
    (SELECT @DATAS := getChildId_bas_basic_tree (#{id})) x 
WHERE find_in_set (ID, @DATAS)

mysql方法的实现:

-- 在navcat中的查询下执行以下命令

drop function if exists getChildId_bas_basic_tree;

DELIMITER //
create function getChildId_bas_basic_tree(rootId varchar(20)) 
returns varchar (1000)
BEGIN 
    DECLARE pTemp VARCHAR(1000);            
    DECLARE cTemp VARCHAR(1000);      -- 节点ID(临时变量)

    SET pTemp = '$';  
    SET cTemp =cast(rootId as CHAR);  -- 把rootId强制转换为字符。

    WHILE cTemp is not null DO  
       SET pTemp = concat(pTemp,',',cTemp);  -- 把所有节点连接成字符串。
       SELECT group_concat(id) INTO cTemp FROM bas_basic_tree   
       WHERE FIND_IN_SET(pid,cTemp)>0;
    END WHILE;  
    RETURN pTemp;  
END //
DELIMITER ;

2.多个子递归查询的实现

oracle中使用示例代码:

SELECT
   T.ID
FROM
   bas_basic_tree T CONNECT BY PRIOR T.ID = T.PID
   START WITH T.ID in( #{ids} ) 
   
-- 其中ids比如是 ('1', '2') 这种

mysql中使用示例代码:

SELECT
   *
FROM
   bas_basic_tree T ,
   (select @DATAK := 
       (   
           SELECT
               -- 使用该方法把所有的ID用逗号分割连接成一个字符串
               group_concat(T.ID)
           FROM
               bas_basic_tree T
           WHERE
           NAME LIKE #{orgname}
           -- 括号里面查询出来的结果类似与 '1,2' 这种
       )
   ) z,
   (SELECT @DATAS := getParentId_bas_basic_tree_more (@DATAK) ) x 
WHERE find_in_set (T.ID, @DATAS)

-- 注意这里select @DATAK 与 SELECT @DATAS 顺序不能乱,否则会出现数据错误

mysql方法的实现:

drop function if exists getChildId_bas_basic_tree_more;

DELIMITER //
create function getChildId_bas_basic_tree_more(nodes varchar(1000)) 
returns varchar (5000)

BEGIN 
       DECLARE pTemp VARCHAR(1000);             
       DECLARE cTemp VARCHAR(5000);  
      
      SET @array_content= nodes; 
       SET @i=1;
       SET @count=CHAR_LENGTH(@array_content) -CHAR_LENGTH(REPLACE(@array_content,',','')) + 1;
      SET pTemp = '$';  

       WHILE @i <= @count DO
          SET cTemp = SUBSTRING_INDEX(SUBSTRING_INDEX(@array_content,',',@i),',',-1);
          WHILE cTemp is not null DO  
            SET pTemp = concat(pTemp,',',cTemp);  
            SELECT group_concat(id) INTO cTemp FROM bas_basic_tree   
            WHERE FIND_IN_SET(pid,cTemp) > 0;
          END WHILE;  
          SET @i = @i + 1; 
      END WHILE; 
      
       RETURN pTemp;  

END //
DELIMITER ;

实现父递归查询

1.单个父递归查询的实现

oracle中使用示例代码:

SELECT
   T.ID
FROM
   bas_basic_tree T CONNECT BY PRIOR T.PID = T.ID
   START WITH T.ID = #{id}

mysql中使用示例代码:

SELECT
   ID
FROM 
   bas_basic_tree T,
   (SELECT @LIST := getParentId_bas_basic_tree (#{id})) x 
WHERE find_in_set (ID, @LIST)

mysql方法的实现:

-- 在navcat中的查询下执行以下命令

drop function if exists getParentId_bas_basic_tree;

DELIMITER //
create function getParentId_bas_basic_tree(rootId varchar(20)) 
returns varchar (1000)
BEGIN 
   DECLARE fid varchar(100) default ''; 
   DECLARE str varchar(1000) default rootId; -- 节点ID(临时变量)
 
    WHILE rootId is not null  do 
        SET fid =(SELECT pid FROM bas_basic_tree WHERE id = rootId); 
        IF fid is not null THEN 
            SET str = concat(str, ',', fid); 
            SET rootId = fid; 
        ELSE 
            SET rootId = fid; 
        END IF; 
    END WHILE; 
   return str;
END //
DELIMITER ;

2.多个父递归查询的实现

oracle中使用示例代码:

SELECT
   T.ID
FROM
   bas_basic_tree T CONNECT BY PRIOR T.PID = T.ID
   START WITH T.ID in( #{ids} ) 
   
-- 其中ids比如是 ('1', '2') 这种

mysql中使用示例代码:

SELECT
   T.*
FROM
   bas_basic_tree T ,
   (select @DATAK := 
       (
           SELECT
               -- 使用该方法把所有的ID用逗号分割连接成一个字符串
               group_concat(T.ID)
           FROM
               bas_basic_tree T
           WHERE
           NAME LIKE #{orgname}
           -- 括号里面查询出来的结果类似与 '1,2' 这种
       )
   ) zz,
   (SELECT @DATAS := getParentId_bas_basic_tree_more (@DATAK) ) x
WHERE find_in_set (T.ID, @DATAS) 

mysql方法的实现:

-- 在navcat中的查询下执行以下命令

drop function if exists getParentId_bas_basic_tree_more;

DELIMITER //
create function getParentId_bas_basic_tree_more(nodes varchar(1000)) 
returns varchar (5000)

BEGIN
      DECLARE pTemp VARCHAR(1000);              
       DECLARE cTemp VARCHAR(5000);  
      DECLARE xTemp varchar(100); 

      SET @array_content= nodes; 
       SET @i=1;
       SET @count=CHAR_LENGTH(@array_content) -CHAR_LENGTH(REPLACE(@array_content,',','')) + 1;
      SET pTemp = nodes;  

       WHILE @i <= @count DO
          SET cTemp=SUBSTRING_INDEX(SUBSTRING_INDEX(@array_content,',',@i),',',-1);
          WHILE cTemp is not null DO  
            SET xTemp = (SELECT pid FROM bas_basic_tree WHERE id = cTemp); 
            IF xTemp is not null THEN 
               SET pTemp = concat(pTemp, ',', xTemp); 
               set cTemp = xTemp;
            ELSE 
               set cTemp = xTemp;
            END IF;
          END WHILE;  
          SET @i = @i + 1; 
      END WHILE; 
       RETURN pTemp;  
END //

DELIMITER ;
上一篇下一篇

猜你喜欢

热点阅读