mySQL中构建树形结构(类似oracle的树形结构)

 

老用oracle,时间长了,一时之间在mysql上进行操作,还真的不顺手,一些特殊属性还要去查找它的manual,比如分页查询limit 之类.

应用之中碰见一个关于组织机构的树形查询,本来用oracle的自身特性,一句SQL搞定了,但在mysql试了老半天都不成(也说自已是新手,一些东西写出来老出错),在网上查了大半天,也就那两个SQL,运行起来,mysql都死掉了....自已参考以前的在SQL server中写的语句,一个下午才把它搞出来,别小看了mysql,真用起来还不是那么容易的..

下面给出我用的数据表结构各数据 / 树形结构的存储过程实现  /树形结构的查询结果 都贴出来 ,如果你的项目中有应用,请参照修改.
1.数据表(org   --组织机构表名)
 - ----------------------------
 -- Table structure for org
 -- ----------------------------
 DROP TABLE IF EXISTS `org`;
 CREATE TABLE `org` (
   `ORGID` decimal(10,0) DEFAULT NULL,
   `CODE` varchar(20) DEFAULT NULL,
   `NAME` varchar(50) DEFAULT NULL,
   `ORGPID` decimal(10,0) DEFAULT NULL,
   `TEL` varchar(20) DEFAULT NULL,
   `FAX` varchar(20) DEFAULT NULL,
   `ADDRESS` varchar(100) DEFAULT NULL,
   `DES` text,
   `PRINCIPAL` varchar(20) DEFAULT NULL,
   `LDAPDN` varchar(200) DEFAULT NULL,
   `FLAG` varchar(20) DEFAULT NULL,
   `SORTINDEX` decimal(10,0) DEFAULT NULL,
   `COMPANYFLAG` decimal(10,0) DEFAULT NULL,
   UNIQUE KEY `PK_ORG` (`ORGID`)
 ) ENGINE=InnoDB DEFAULT CHARSET=gb2312;

 -- ----------------------------
 -- Records
 -- ----------------------------
 INSERT INTO `org` VALUES ('8', null, '质量控制部', '1', null, null, null, null, null, 'ou=质量控制部,o=xxxxxx有限公司', null, '9', '0');
 INSERT INTO `org` VALUES ('9', null, '财务管理部', '1', null, null, null, null, null, 'ou=财务管理部,o=xxxxxx有限公司', null, '3', '0');
 INSERT INTO `org` VALUES ('14', null, '安全保卫部', '1', null, null, null, null, null, 'ou=安全保卫部,o=xxxxxx有限公司', null, '12', '0');
 INSERT INTO `org` VALUES ('3', null, '综合事务部', '1', null, null, null, null, null, 'ou=综合事务部,o=xxxxxx有限公司', null, '2', '0');
 INSERT INTO `org` VALUES ('12', null, '航机维修部', '1', null, null, null, null, null, 'ou=航机维修部,o=xxxxxx有限公司', null, '7', '0');
 INSERT INTO `org` VALUES ('1', null, 'xxxxxx有限公司', '0', null, null, null, null, null, 'o=xxxxxx有限公司', null, '0', null);
 INSERT INTO `org` VALUES ('0', null, 'rootNode', '0', null, null, null, null, null, null, null, null, null);
 INSERT INTO `org` VALUES ('5', null, '人力资源部', '1', null, null, null, null, null, 'ou=人力资源部,o=xxxxxx有限公司', null, '4', '0');
 INSERT INTO `org` VALUES ('6', null, '市场营销部', '1', null, null, null, null, null, 'ou=市场营销部,o=xxxxxx有限公司', null, '6', '0');
 INSERT INTO `org` VALUES ('10', null, '航机服务分公司', '1', null, null, null, null, null, 'ou=航机服务分公司,o=xxxxxx有限公司', null, '8', '0');
 INSERT INTO `org` VALUES ('11', null, '采购供应部', '1', null, null, null, null, null, 'ou=采购供应部,o=xxxxxx有限公司', null, '11', '0');
 INSERT INTO `org` VALUES ('19', null, '系统开发人员', '1', null, null, null, '系统开发人员', null, 'ou=系统开发人员,o=xxxxxx有限公司', null, '99', '0');
 INSERT INTO `org` VALUES ('20', null, '地面销售分公司', '1', null, null, null, null, null, 'ou=地面销售分公司,o=xxxxxx有限公司', null, '10', '0');
 INSERT INTO `org` VALUES ('22', null, '公司领导', '1', null, null, null, null, null, 'ou=公司领导,o=xxxxxx有限公司', null, '1', '0');
 INSERT INTO `org` VALUES ('23', null, '机供品销售分公司', '1', null, null, null, null, null, 'ou=机供品销售分公司,o=xxxxxx有限公司', null, '13', '0');
 INSERT INTO `org` VALUES ('28', null, '运行控制部', '1', null, null, null, null, null, 'ou=运行控制部,o=xxxxxx有限公司', null, '5', '0');
 INSERT INTO `org` VALUES ('29', null, '新机场办公室', '1', null, null, null, null, null, 'ou=新机场办公室,o=xxxxxx有限公司', null, '14', '0');
 INSERT INTO `org` VALUES ('30', null, '3LEVEL', '3', null, null, null, null, null, null, null, null, null);
 INSERT INTO `org` VALUES ('31', null, '4LEVEL', '30', null, null, null, null, null, null, null, null, null);
 INSERT INTO `org` VALUES ('32', null, '5LEVEL', '31', null, null, null, null, null, null, null, null, null);

 2. 生成组织机构树形结构的存储过程  (出于结果预览的需要,加入一个数据表以展示数据,应用时可以只用临时表)
 drop procedure if exists GetSubtreeInfoOfTable;
 /**
 * 功能说明:    适于MySQL中关于组织机构的树形结构查询  
 *  int TOP_ORG_ID  树形结构的根结点ID(完整树或其中一个分支)
 * int     FLAG   如果为1则代表查询整个树的树形结构    0则按照传入的TOP_ORG_ID值来查询一个分支的树形结构
 * 返回:返回树形结构的结果集 (leveL,orgid,orgpid,name :分别表示: 层次,部门ID,部门的上级ID,部门名称)
 * Author :ketty  2009-05
 */
 create procedure GetSubtreeInfoOfTable(IN TOP_ORG_ID int,IN FLAG int)

 BEGIN

 declare level bigint(20)  ;
 declare fundRows bigint(20)  ;
 declare xRows bigint(20)  ;
 set level=1,fundRows=0,xRows=0;
 delete from orgTemptree;
 drop TEMPORARY  TABLE if exists tmp_tree_table;
 drop TEMPORARY  TABLE if exists tmp_orgID_table;
  /* tmp_tree_table用来保存树形结构的真实数据*/  
 CREATE TEMPORARY TABLE tmp_tree_table  (
  level integer ,orgid integer,orgpid integer,name varchar(1000),sortIDString varchar(1000),sortIndex int )  DEFAULT CHARACTER SET UTF8;
   /* tmp_orgID_table用来保存树形结构的level与orgID值,在相同的查询中,不能引用TEMPORARY表1次,所以只作查询时辅助表 */
 CREATE TEMPORARY TABLE tmp_orgID_table   
  ( level integer ,  orgid integer,sortIDString varchar(1000) ) DEFAULT CHARACTER SET UTF8;   


 /*如果是查询整个树形结构时,需要重设根结点的起始位置(从树的根开始)*/
 if FLAG>0  THEN
   SET TOP_ORG_ID= (SELECT MIN(orgid)+1 FROM org) ;
 END IF;
 /*发现第一个根记录,并记录到树形结构表中 */
  set fundRows=1;  
 /*  写入根结点数据  此根结点不一定是保存树形的最底层根,而是一个分支的根  */
   INSERT  INTO  tmp_tree_table (level,orgid,orgpid,name,sortIDString,sortIndex)
  SELECT level,orgid, orgpid,name,CONCAT('',TOP_ORG_ID),sortIndex from org where orgid=TOP_ORG_ID;
   INSERT  INTO  tmp_orgID_table (level,orgid,sortIDString)
  SELECT level,orgid,CONCAT('',TOP_ORG_ID) from org where orgid=TOP_ORG_ID;
  
 /*   这里的语句是用来作调试用的
     INSERT  INTO  tmp_tree_table (leveL,orgid,orgpid,name )
    values( -1,fundRows,xRows,CONCAT('insert rows information','-',fundRows)) ;*/

 /*在相同的查询中,不能引用TEMPORARY表1次以上  所以这里用两个临时表进行交叉分析以得到数据的树形层次结构  */

 WHILE   fundRows >0   do
   SET level = level+1 ;   /* 将 level=level+1*/ 
   
   INSERT INTO tmp_tree_table (level,orgid,orgpid,name,sortIDString,sortIndex)
   SELECT  level,org.orgid,org.orgpid,org.name,  CONCAT( tmp_orgID_table.orgid,'-',org.orgid) ,sortIndex 
   FROM org , tmp_orgID_table 
   WHERE org.orgpid = tmp_orgID_table.orgid AND tmp_orgID_table.level = level-1;
    
   INSERT INTO tmp_orgID_table (level,orgid,sortIDString)
   SELECT  level,org.orgid,  CONCAT( tmp_tree_table.orgid,'-',org.orgid)
   FROM org , tmp_tree_table 
   WHERE org.orgpid = tmp_tree_table.orgid AND tmp_tree_table.level = level-1;
   
   select count(*) into fundRows
   FROM org , tmp_tree_table 
   WHERE org.orgpid = tmp_tree_table.orgid AND tmp_tree_table.level = level-1;
 

  END WHILE;

 /*从临时表中返回得到树形结构数据  */
  /*  select * from tmp_tree_table;
 /*清空临时表中中的数据 */
    insert into orgTemptree  select * from  tmp_tree_table order by sortIDString;
    truncate table tmp_tree_table;
    truncate table tmp_orgID_table;
 END

3.  查询结果展示
 先执行  call GetSubtreeInfoOfTable(1,0)

 再执行   select * from orgTempTree ;
 树形结构数据显示如下:
 level(层次)  orgID  orgPID        orgName                        sortIDString(排序用) sortIndex
 1                1          0               xxxxxxxxxxxx有限公司                1                         0
 2               10         1                航机服务分公司                           1-10                    8
 2               11         1                 采购供应部                               1-11                      11
 2               12         1                  航机维修部                              1-12                      7
 2  14  1 安全保卫部   1-14    12
 2  19  1 系统开发人员   1-19    99
 2  20  1 地面销售分公司   1-20    10
 2  22  1 公司领导    1-22    1
 2  23  1 机供品销售分公司  1-23    13
 2  28  1 运行控制部   1-28    5
 2  29  1 新机场办公室   1-29    14
 2  3  1 综合事务部   1-3    2
 2  5  1 人力资源部   1-5    4
 2  6  1 市场营销部   1-6    6
 2  8  1 质量控制部   1-8    9
 2  9  1 财务管理部   1-9    3
 3                30          3                  3LEVEL                                   3-30 
 4                 31         30                4LEVEL                                   30-31 
 5                 32          31               5LEVEL                                   31-32 

 

以上是经过测试并在项目中运行的代码,如果转载,请注明出处!!

 

你可能感兴趣的:(oracle,mysql,tree,table,null,insert)