关于SQL递归查询在不同数据库中的实现方法
比如表结构数据如下:
Table:Tree
ID Name ParentId
1 一级 0
2 二级 1
3 三级 2
4 四级 3
SQL SERVER 2005查询方法:
//上查
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 四级
查询方法:
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中的查询方法:
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 中的查询方法:
//定义一个依据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/),原因在于我的逻辑写错了,存在死循环,现已修正,新的方法如下:
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
说明:以上知识点均来源于网上,我这里只是做一个合计总结。
关于SQL递归查询在不同数据库中的实现方法的更多相关文章
- 怎样用SQL语句查询一个数据库中的所有表?
怎样用SQL语句查询一个数据库中的所有表? --读取库中的所有表名 select name from sysobjects where xtype='u'--读取指定表的所有列名select nam ...
- SQL点滴12—SQL Server备份还原数据库中的小把戏
原文:SQL点滴12-SQL Server备份还原数据库中的小把戏 备份数据库时出现一个不太了解的错误 ,错误信息“is formatted to support 1 media families, ...
- SQL语句往Oracle数据库中插入日期型数据(to_date的用法)
Oracle 在操作数据库上相比于其他的 T-sql 有微小的差别,但是在插入时间类型的数据是必须要注意他的 to_date 方法,具体的情况如下: --SQL语句往Oracle数据库中插入日期型数据 ...
- SQL Server 删除当前数据库中所有数据库 ,无视约束
Sql Server中清空所有数据表中的记录 清空所有数据表中的记录: exec sp_msforeachtable @Command1 ='truncate table ?' 删除所有数据表: e ...
- sql脚本来获取数据库中的所有表结构了
sql脚本来获取数据库中的所有表结构了,代码如下: use AdventureWorks2008 go SELECT (case when a.colorder=1 then d.name else ...
- excel数据通过构建sql语句导入到数据库中
拿到一张excel数据表格,数据格式如下图所示: 2.根据excel数据结果,构建保存excel数据的表结构 CREATE TABLE #tmpExcel(IP VARCHAR(100),IPAddr ...
- 从excel表中生成批量SQL,将数据录入到数据库中
excel表格中有许多数据,需要将数据导入数据库中,又不能一个一个手工录入,可以生成SQL,来批量操作. 1.首先在第二行的H列,插入函数:=CONCATENATE("INSERT ...
- SQL触发器批量删除数据库中的表
以下通过触发器批量删除数据库中的表,SQL2008已验证 DECLARE @Table NVARCHAR() DECLARE @Count Int = DECLARE tmpCur CURSOR FO ...
- Sql Server 2008 R2数据库中插入中文变成了问号
通过Insert语句插入数据库中,结果中文都变成了乱码.原因是在数据库中有一个属性需要设置,可以通过Sql server manager studio来进行设置,也要可以通过代码来设置 ...
随机推荐
- 解决Django站点admin管理页面样式表(CSS style)丢失
参照这篇教程激活完django自带服务器的admin管理页面后,照着教程所描述的那样,尝试打开http://127.0.0.1:8000/admin/,发现自己的浏览器显示如下 很明显可以看出,虽然业 ...
- Linux(CentOS 6.5)下配置Mono和Jexus并且部署ASP.NET MVC5
1.开篇说明 a. 首先我在写这篇博客之前,已经在自己本地配置了mono和jexus并且成功部署了asp.net mvc项目,我也是依赖于在网上查找的各种资料来配置环境并且部署项目的,而其在网上也已有 ...
- Actor的原理
先从著名的c10k问题谈起.有一个叫Dan Kegel的人在网上(http://www.kegel.com/c10k.html)提出:现在的硬件应该能够让一台机器支持10000个并发的client.然 ...
- Viewbox在UWP开发中的应用
Windows 8.1 与Windows Phone 8.1的UAP应用,终于在Windows 10上统一到了UWP之下.原来3个不同的project也变为一个.没有了2套xaml页面,我们需要用同一 ...
- 作业二--注册GitHub的过程
第一步:打开GitHub官网https://github.com/,在界面中输入账号名称.邮箱.密码,然后点击注册按钮. 第二步:注册完成后,选择Free免费账号完成初始设置. 第三步:验证邮箱,打开 ...
- 走进AngularJs(七) 过滤器(filter)
过滤器(filter)正如其名,作用就是接收一个输入,通过某个规则进行处理,然后返回处理后的结果.主要用在数据的格式化上,例如获取一个数组中的子集,对数组中的元素进行排序等.ng内置了一些过滤器,它们 ...
- Unity3D手游开发实践
<腾讯桌球:客户端总结> 本次分享总结,起源于腾讯桌球项目,但是不仅仅限于项目本身.虽然基于Unity3D,很多东西同样适用于Cocos.本文从以下10大点进行阐述: 架构设计 原生插件/ ...
- JavaScript思维导图—变量
JavaScript思维导图-来自@王子墨http://julying.com/blog/the-features-of-javascript-language-summary-maps/
- Azure China (8) 使用Azure PowerShell创建虚拟机,并设置固定Virtual IP Address和Private IP
<Windows Azure Platform 系列文章目录> 本文介绍的是由世纪互联运维的Windows Azure China. 相比于Global Azure (http://www ...
- Java中常用修饰符使用汇总
修饰符汇总: 一:public protected default private 修饰类,修饰方法,修饰属性,修饰代码块. 类: 顶级类只能用public 修饰,顶级类不能使用private 和p ...