老用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
以上是经过测试并在项目中运行的代码,如果转载,请注明出处!!