关于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

说明:以上知识点均来源于网上,我这里只是做一个合计总结。

本文转自 梦在旅途 博客园博客,原文链接:http://www.cnblogs.com/zuowj/p/4872385.html  ,如需转载请自行联系原作者

相关文章
|
9天前
|
SQL 关系型数据库 MySQL
数据库开发之SQL简介以及DDL的详细解析
数据库开发之SQL简介以及DDL的详细解析
24 0
|
2天前
|
安全 数据管理 数据库
数据管理DMS产品使用合集之要将某个DMS实例中的特定数据库授权给某个用户进行查询,操作步骤是怎样的
阿里云数据管理DMS提供了全面的数据管理、数据库运维、数据安全、数据迁移与同步等功能,助力企业高效、安全地进行数据库管理和运维工作。以下是DMS产品使用合集的详细介绍。
|
2天前
|
关系型数据库 数据库 开发者
关系型数据库查询避免SELECT *
有时候你可能会遇到需要选择表中的所有列的情况,但这应该是例外而不是常态。在大多数情况下,你应该尽量避免使用 `SELECT *`。
7 1
|
2天前
|
SQL 分布式计算 关系型数据库
云原生数据仓库产品使用合集之可以把ADB MySQL湖仓版数据库做成页面查询的数据库吗
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
|
6天前
|
SQL 缓存 数据库
在Python Web开发过程中:数据库与缓存,如何使用ORM(例如Django ORM)执行查询并优化查询性能?
在Python Web开发中,使用ORM如Django ORM能简化数据库操作。为了优化查询性能,可以:选择合适索引,避免N+1查询(利用`select_related`和`prefetch_related`),批量读取数据(`iterator()`),使用缓存,分页查询,适时使用原生SQL,优化数据库配置,定期优化数据库并监控性能。这些策略能提升响应速度和用户体验。
8 0
|
7天前
|
SQL Java 数据库连接
Java从入门到精通:2.3.2数据库编程——了解SQL语言,编写基本查询语句
Java从入门到精通:2.3.2数据库编程——了解SQL语言,编写基本查询语句
|
8天前
|
SQL XML 数据库
sql导入数据库命令
在SQL Server中,数据库导入可通过多种方式实现:1) 使用SSMS的“导入数据”向导从各种源(如Excel、CSV)导入;2) BULK INSERT语句适用于导入文本文件;3) bcp命令行工具进行批量数据交换;4) OPENROWSET函数直接从外部数据源(如Excel)插入数据。在操作前,请记得备份数据库,并可能需对数据进行预处理以符合SQL Server要求。注意不同方法可能依版本和配置而异。
|
9天前
|
SQL 分布式计算 资源调度
一文解析 ODPS SQL 任务优化方法原理
本文重点尝试从ODPS SQL的逻辑执行计划和Logview中的执行计划出发,分析日常数据研发过程中各种优化方法背后的原理,覆盖了部分调优方法的分析,从知道怎么优化,到为什么这样优化,以及还能怎样优化。
103456 0
|
SQL 存储 移动开发
PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(四)|学习笔记
快速学习3 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(四)
384 0
 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(四)|学习笔记
|
SQL 关系型数据库 数据库
3 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(三)|学习笔记
快速学习3 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(三)
306 0