1.ORACLE 递归查询
递归查询,用于查询当前对象的所有下级对象
例如:
select code from table start with code in
<foreach collection="dto.codes" open="(" separator="," close=")" item="code">
#{code}
</foreach>
connect by prior code=parentCode
2.SQL SERVER 递归查询
正文
SQL SERVER 2005之前的版本只能用函数方法实现,SQL SERVER
2005之后新增了CTE功能,可以利用CTE实现递归查询;CTE:公用表达式Common Table Expression 是SQL SERVER 2005版本之后引入的一个特性;
填充测试数据
Create table GroupInfo([Id] int,[GroupName] nvarchar(50),[ParentGroupId] int)
Insert GroupInfo
select 0,'某某大学',null union all
select 1,'外语学院',0 union all
select 2,'英语专业',1 union all
select 3,'日语专业',1 union all
select 4,'英语专业一班',2 union all
select 5,'英语专业二班',2 union all
select 6,'日语专业一班',3 union all
select 7,'日语专业二班',3 union all
select 8, '法学院',0 union all
select 9, '刑法学专业',8 union all
select 10,'经济法学专业',8 union all
select 11,'刑法学专业一班',9 union all
select 12,'刑法学专业二班',9 union all
select 13,'经济法学专业一班',10 union all
select 14,'经济法学专业二班',10
效果图
递归实现Demo
1、根据指定的节点向上获取所有父节点,向下获取所有子节点
–根据指定的节点向下获取所有子节点
with
CTE
as
(
select * from GroupInfo where Id=1
union all
select G.* from CTE inner join GroupInfo as G
on CTE.Id=G.ParentGroupId
)
select * from CTE order by Id
–根据指定的节点向上获取所有父节点
with
CTE
as
(
select * from GroupInfo where Id=14
union all
select G.* from CTE inner join GroupInfo as G
on CTE.ParentGroupId=G.Id
)
select * from CTE order by Id
2、构造递归路径
1 --构造递归路径
with
CTE
as
(
select Id,GroupName,ParentGroupId,GroupPath=CAST( GroupName as nvarchar(max)) from GroupInfo where Id=1
union all
select G.*,CAST(CTE.GroupPath+'//'+G.GroupName as nvarchar(max)) as GroupPath from CTE
inner join GroupInfo as G
on CTE.Id=G.ParentGroupId
)
select * from CTE
3、分组递归,将同一条分支上节点放到一起
–通过id字段的字符串的拼接,形成sort字段,再通过sort排序,来实现同一分支上的节点放到一起
WITH
CTE
AS
(
SELECT * ,CAST(RIGHT('000' + CAST([Id] AS VARCHAR), 3) AS VARCHAR(MAX)) AS sort FROM GroupInfo
WHERE ParentGroupId = 0
UNION ALL
SELECT GroupInfo.* ,CAST(sort + RIGHT('000' + CAST(GroupInfo.[Id] AS VARCHAR),3) AS VARCHAR(MAX)) AS sort
FROM CTE
INNER JOIN GroupInfo ON CTE.Id = GroupInfo.ParentGroupId
)
SELECT * FROM CTE ORDER BY sort
4、递归层级查询(查询出节点所属的层级)
–查询节点层级
WITH CTE AS (
SELECT *,1 AS [Level] FROM GroupInfo WHERE ParentGroupId=0
UNION ALL
SELECT G.*,CTE.Level+1 FROM GroupInfo as G
JOIN CTE ON CTE.Id =G.ParentGroupId
)
SELECT * FROM CTE
3.MYSQL的递归查询
find_in_set 函数的语法: FIND_IN_SET(str,strList) str 要查询的字符串 strList 字段名,参数以“,”分隔,如(1,2,6,8) 查询字段(strList)中包含的结果,返回结果null或记录mysql递归查询所有数据的方法:利用【find_in_set()】函数和【group_concat()】函数实现递归查询,代码为【SELECT
queryChildrenAreaInfo(1);】。
1、创建表
DROP TABLE IF EXISTS `t_areainfo`;
CREATE TABLE `t_areainfo` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`level` int(11) DEFAULT '0',
`name` varchar(255) DEFAULT '0',
`parentId` int(11) DEFAULT '0',
`status` int(11) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8;
2、初始数据
INSERT INTO `t_areainfo` VALUES ('1', '0', '中国', '0', '0');
INSERT INTO `t_areainfo` VALUES ('2', '0', '华北区', '1', '0');
INSERT INTO `t_areainfo` VALUES ('3', '0', '华南区', '1', '0');
INSERT INTO `t_areainfo` VALUES ('4', '0', '北京', '2', '0');
INSERT INTO `t_areainfo` VALUES ('5', '0', '海淀区', '4', '0');
INSERT INTO `t_areainfo` VALUES ('6', '0', '丰台区', '4', '0');
INSERT INTO `t_areainfo` VALUES ('7', '0', '朝阳区', '4', '0');
INSERT INTO `t_areainfo` VALUES ('8', '0', '北京XX区1', '4', '0');
INSERT INTO `t_areainfo` VALUES ('9', '0', '北京XX区2', '4', '0');
INSERT INTO `t_areainfo` VALUES ('10', '0', '北京XX区3', '4', '0');
INSERT INTO `t_areainfo` VALUES ('11', '0', '北京XX区4', '4', '0');
INSERT INTO `t_areainfo` VALUES ('12', '0', '北京XX区5', '4', '0');
INSERT INTO `t_areainfo` VALUES ('13', '0', '北京XX区6', '4', '0');
INSERT INTO `t_areainfo` VALUES ('14', '0', '北京XX区7', '4', '0');
INSERT INTO `t_areainfo` VALUES ('15', '0', '北京XX区8', '4', '0');
INSERT INTO `t_areainfo` VALUES ('16', '0', '北京XX区9', '4', '0');
INSERT INTO `t_areainfo` VALUES ('17', '0', '北京XX区10', '4', '0');
INSERT INTO `t_areainfo` VALUES ('18', '0', '北京XX区11', '4', '0');
INSERT INTO `t_areainfo` VALUES ('19', '0', '北京XX区12', '4', '0');
INSERT INTO `t_areainfo` VALUES ('20', '0', '北京XX区13', '4', '0');
3、向下递归
利用find_in_set()函数和group_concat()函数实现递归查询:
DROP FUNCTION IF EXISTS queryChildrenAreaInfo;
DELIMITER ;;
CREATE FUNCTION queryChildrenAreaInfo(areaId INT)
RETURNS VARCHAR(4000)
BEGIN
DECLARE sTemp VARCHAR(4000);
DECLARE sTempChd VARCHAR(4000);
SET sTemp='$';
SET sTempChd = CAST(areaId AS CHAR);
WHILE sTempChd IS NOT NULL DO
SET sTemp= CONCAT(sTemp,',',sTempChd);
SELECT GROUP_CONCAT(id) INTO sTempChd FROM t_areainfo WHERE FIND_IN_SET(parentId,sTempChd)>0;
END WHILE;
RETURN sTemp;
END
;;
DELIMITER ;
注意:如果创建函数错误,请先执行以下语句:
set global log_bin_trust_function_creators=TRUE;
4、调用方式
SELECT queryChildrenAreaInfo(1);
查询id为"4"下面的所有节点
SELECT * FROM t_areainfo WHERE FIND_IN_SET(id,queryChildrenAreaInfo(4));