关于SQL递归查询在不同数据库中的实现方法
比如表结构数据如下:
Table:Tree
ID Name ParentId
1 一级 0
2 二级 1
3 三级 2
4 四级 3
SQL SERVER 2005查询方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | //上查 with tmpTree as ( select * from Tree where Id=2 union all select p.* from tmpTree inner join Tree p on p.Id=tmpTree.ParentId ) select * from tmpTree //下查 with tmpTree as ( select * from Tree where Id=2 union all select s.* from tmpTree inner join Tree s on s.ParentId=tmpTree.Id ) select * from tmpTree |
SQL SERVER 2008及以后版本,还可用如下方法:
增加一列TID,类型设为:hierarchyid(这个是CLR类型,表示层级),且取消ParentId字段,变成如下:(表名为:Tree2)
TId Id Name
0x 1 一级
0x58 2 二级
0x5B40 3 三级
0x5B5E 4 四级
查询方法:
1 2 3 4 5 6 7 8 9 | SELECT *,TId.GetLevel() as [ level ] FROM Tree2 --获取所有层级 DECLARE @ParentTree hierarchyid SELECT @ParentTree=TId FROM Tree2 WHERE Id=2 SELECT *,TId.GetLevel() AS [ level ] FROM Tree2 WHERE TId.IsDescendantOf(@ParentTree)=1 --获取指定的节点所有下级 DECLARE @ChildTree hierarchyid SELECT @ChildTree=TId FROM Tree2 WHERE Id=3 SELECT *,TId.GetLevel() AS [ level ] FROM Tree2 WHERE @ChildTree.IsDescendantOf(TId)=1 --获取指定的节点所有上级 |
可参见相关文章:http://blog.csdn.net/szstephenzhou/article/details/8277667
ORACLE中的查询方法:
1 2 3 4 5 6 7 8 9 | SELECT * FROM Tree START WITH Id=2 CONNECT BY PRIOR ID=ParentId --下查 SELECT * FROM Tree START WITH Id=2 CONNECT BY ID= PRIOR ParentId --上查 |
可参见相关文章:http://blog.csdn.net/super_marioli/article/details/6253639
MYSQL 中的查询方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | //定义一个依据ID查询所有父ID为这个指定的ID的字符串列表,以逗号分隔 CREATE DEFINER=`root`@`localhost` FUNCTION `getChildLst`(rootId int ,direction int ) RETURNS varchar (1000) CHARSET utf8 BEGIN DECLARE sTemp VARCHAR (5000); DECLARE sTempChd VARCHAR (1000); SET sTemp = '$' ; IF direction=1 THEN SET sTempChd = cast (rootId as CHAR ); ELSEIF direction=2 THEN SELECT cast (ParentId as CHAR ) into sTempChd FROM Tree WHERE Id=rootId; END IF; WHILE sTempChd is not null DO SET sTemp = concat(sTemp, ',' ,sTempChd); SELECT group_concat(id) INTO sTempChd FROM Tree where (direction=1 and FIND_IN_SET(ParentId,sTempChd)>0) or (direction=2 and FIND_IN_SET(Id,sTempChd)>0); END WHILE; RETURN sTemp; END //查询方法: select * from tree where find_in_set(id,getChildLst(1,1)); --下查 select * from tree where find_in_set(id,getChildLst(1,2)); --上查 |
补充说明:上面这个方法在下查是没有问题,但在上查时会出现问题(详见博问:http://q.cnblogs.com/q/76375/),原因在于我的逻辑写错了,存在死循环,现已修正,新的方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | CREATE DEFINER=`root`@`localhost` FUNCTION `getChildLst`(rootId int ,direction int ) RETURNS varchar (1000) CHARSET utf8 BEGIN DECLARE sTemp VARCHAR (5000); DECLARE sTempChd VARCHAR (1000); SET sTemp = '$' ; SET sTempChd = cast (rootId as CHAR ); IF direction=1 THEN WHILE sTempChd is not null DO SET sTemp = concat(sTemp, ',' ,sTempChd); SELECT group_concat(id) INTO sTempChd FROM Tree where FIND_IN_SET(ParentId,sTempChd)>0; END WHILE; ELSEIF direction=2 THEN WHILE sTempChd is not null DO SET sTemp = concat(sTemp, ',' ,sTempChd); SELECT group_concat(ParentId) INTO sTempChd FROM Tree where FIND_IN_SET(Id,sTempChd)>0; END WHILE; END IF; RETURN sTemp; END |
这样递归查询就很方便了。
可参见相关文章:http://blog.csdn.net/jackiehome/article/details/6803978
说明:以上知识点均来源于网上,我这里只是做一个合计总结。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构