mysql递归查询,mysql中从子类ID查询所有父类(做无限分类经常用到)

由于mysql 不支持类似 oracle with ...connect的 递归查询语法
之前一直以为类似的查询要么用存储过程要么只能用程序写递归查询.

现在发现原来一条sql语句也是可以搞定的

先来看数据表的结构如下:

id  name    parent_id 

--------------------------- 
1   Home        0 
2   About       1 
3   Contact     1 
4   Legal       2 
5   Privacy     4 
6   Products    1 
7   Support     1 
我要的要求是根据一个分类ID(这个分类ID可能是一个子分类),得到所有的父分类,下面是相应的SQL:

SELECT T2.id, T2.name 
FROM ( 
    SELECT 
        @r AS _id, 
        (SELECT @r := parent_id FROM table1 WHERE id = _id) AS parent_id, 
        @l := @l + 1 AS lvl 
    FROM 
        (SELECT @r := 5, @l := 0) vars, 
        table1 h 
    WHERE @r <> 0) T1 
JOIN table1 T2 
ON T1._id = T2.id 
ORDER BY T1.lvl DESC;

父类查询所有子类函数

CREATE FUNCTION getChildeIds (rootId INT) RETURNS VARCHAR (1000) 
BEGIN
  DECLARE sTemp VARCHAR (1000) ;
  DECLARE sTempChd VARCHAR (1000) ;
  SET sTemp = '0' ;
  SET sTempChd = CAST(rootId AS CHAR) ;
  WHILE
SET sTemp = CONCAT(sTemp,',',sTempChd);
    SELECT 
      GROUP_CONCAT(子ID) INTO sTempChd 
    FROM
      platform_depart
    WHERE FIND_IN_SET(父id, sTempChd) > 0 ;
  END WHILE ;
  SET sTemp=substring(sTemp,3);
   RETURN sTemp;
END$$


FIND_IN_SET( ID, getChildeIds (ID) )

!FIND_IN_SET( ID, getChildeIds (ID) )



-- MySql 获取当前节点及递归所有上级节点
-- 参数说明:resultField:查询返回字段,idd 要查询的资源ID值,idFieldName ID字段名,parentIdFieldName 上级ID字段名,tableName 表名,isContainMySelf 是否包含自己
DROP procedure IF EXISTS pro_getParentList;
create procedure pro_getParentList(in resultField varchar(4000),in myid varchar(100),in idFieldName varchar(100),in parentIdFieldName varchar(100),in tableName varchar(100),isContainMySelf int)
begin
    drop table if exists tmpParent;
    CREATE    TABLE tmpParent(temId varchar(100)) ;
    set @tempParentId=myid;
  set @myDoflag=1;
WHILE @myDoflag>0  do
    set @ssss = CONCAT(' select ', parentIdFieldName, ', count(*) INTO  @tempParentId,@myDoflag from ',tableName ,' where ',idFieldName,'=','''',@tempParentId,'''');
        prepare strsql from @ssss;
        execute strsql;
    deallocate prepare strsql;    
    if(@myDoflag>0) THEN
      set @insertSql = CONCAT('INSERT into tmpParent(temId) values (',"'",@tempParentId,"'",')');
      prepare preSql1 from @insertSql;
      execute preSql1;
    deallocate prepare preSql1;
    end if;
end WHILE;
          
         IF (isContainMySelf=1) THEN
            INSERT into tmpParent(temId) values (myid);
         END IF;
 
            SET @fieldSql=concat(' SELECT ',resultField);
            set @strsql = CONCAT(@fieldSql,' from ', tableName,' s ',' inner join  tmpParent t on t.temId=s.',idFieldName,'  order by s.',idFieldName,'  asc');
            prepare preSql from @strsql;
            execute preSql;
  
end

猜你喜欢

转载自blog.csdn.net/ybb350680013/article/details/80721514
今日推荐