SQL数据库实现递归查询的几种代码方法

SQL数据库实现递归查询的几种代码方法
表结构

ProductCategory

CategoryID,Level,ParentCategoryID

数据

1,1,-1

2,1,-1

3,2,1

4,3,3

5,2,2

6,4,5

T-SQL

WITH CategoryTemp(CategoryID,ParentCategoryID)--临时表用来保存查到的Category

(

  SELECT CategoryID,ParentCategoryID FROM ProductCategory WHERE ParentCategoryID<=0--将所有的第一层查出来作为初始数据,需要查第几层或者哪个ParentCategoryID下面所有的 N层,把ParentCategoryID赋相关的值即可

  UNION ALL--查询N层

  SELECT pc.CategoryID,ParentCategoryID FROM ProductCategory pc

  LEFT JOIN CategoryTemp ct ON pc.ParentCategoryID=ct.CategoryID

  WHERE ParentCategoryID>0--因为第一层前面已经查出来了,所以这里把第一层筛选掉

)

SELECT CategoryID,ParentCategoryID FROM CategoryTemp

结果

1,-1

2,-1

3,1

4,3

5,2

6,5

如果把ParentCategoryID赋为2,结果则为

5,2

6,5

实例

ID 是否为部门   部门名   上级ID
1       y                       部门0       1
31     y                       部门1       1
32     n                       张三         31
33     n                       李二         31
34     y                       部门2       31
35     n                       王五         34
35     y                       部门3 34
36     n                       小三         35
我想找询   ID   值为   35   下级的所有人员包括下级部门的所有人员

--创建查询函数
create   function   f_id(
@id   int --要查询的id
)returns   @re   table(id   int,level   int)
as
begin
declare   @l   int
set   @l=0
insert   @re   select   id,@l
from   表  
where   上级id=@id
while   @@rowcount> 0
begin
set   @l=@l+1
insert   @re   select   a.id,@l
from   表   a   join   @re   b   on   a.上级id=b.id   and   b.level=@l-1
end
return
end
go

--调用函数进行查询
select   a.*   from   表   a   join   f_id(35)   b   on   a.id=b.id

联合查询

--测试数据
create   table   表(ID   int,是否为部门   char(1),部门名   varchar(10),上级ID   int)
insert   表   select   1   , 'y ', '部门0 '   ,1
union   all   select   31, 'y ', '部门1 '   ,1
union   all   select   32, 'n ', '张三 '   ,31
union   all   select   33, 'n ', '李二 '   ,31
union   all   select   34, 'y ', '部门2 ',31
union   all   select   35, 'n ', '王五 '   ,34
union   all   select   35, 'y ', '部门3 ',34
union   all   select   36, 'n ', '小三 '   ,35
go

--创建查询函数
create   function   f_id(
@id   int --要查询的id
)returns   @re   table(id   int,level   int)
as
begin
declare   @l   int
set   @l=0
insert   @re   select   id,@l
from   表  
where   上级id=@id
while   @@rowcount> 0
begin
set   @l=@l+1
insert   @re   select   a.id,@l
from   表   a   join   @re   b   on   a.上级id=b.id   and   b.level=@l-1
end
return
end
go

--调用函数进行查询
select   a.*   from   表   a   join   f_id(35)   b   on   a.id=b.id
go

--删除测试
drop   table   表
drop   function   f_id

/*--测试结果

ID                     是否为部门   部门名                 上级ID                
-----------   -----   ----------   -----------  
36                     n           小三                   35

(所影响的行数为   1   行)

时间: 2024-08-19 11:08:08

SQL数据库实现递归查询的几种代码方法的相关文章

mysql主从数据库不同步的2种解决方法

今天发现Mysql的主从数据库没有同步 先上Master库: mysql>show processlist; 查看下进程是否Sleep太多.发现很正常. show master status; 也正常. mysql> show master status; +-------------------+----------+--------------+-------------------------------+ | File | Position | Binlog_Do_DB | Binlo

mysql主从数据库不同步的2种解决方法_Mysql

今天发现Mysql的主从数据库没有同步 先上Master库: mysql>show processlist; 查看下进程是否Sleep太多.发现很正常. show master status; 也正常. mysql> show master status; +-------------------+----------+--------------+-------------------------------+ | File | Position | Binlog_Do_DB | Binlo

C#和asp.net中链接数据库中参数的几种传递方法实例代码_实用技巧

复制代码 代码如下: #region 参数传递方法第一种     //参数设置方法(第一种)      //SqlParameter sp = new SqlParameter("@Name", str_Name);      //SqlParameter sp2 = new SqlParameter("@Pwd", str_Pwd);      //cmd.Parameters.Add(sp);      //cmd.Parameters.Add(sp2);  #

SQL like子句的另一种实现方法(速度比like快)_数据库其它

一般来说使用模糊查询,大家都会想到LIKE  select * from table where a like '%字符%'  如果一个SQL语句中用多个 like模糊查询,并且记录条数很大,那速度一定会很慢.  下面两种方法也可实现模糊查询:  select * from table where patindex('%字符%',a)>0  select * from table where charindex('字符',a)>0  经测试这两种方法比LIKE速度要快. 一.[SQL] pat

SQL数据库开发中的一些精典代码

1.按姓氏笔画排序: select * From TableName Order By CustomerName Collate Chinese_PRC_Stroke_ci_as 2.数据库加密: select encrypt('原始密码') select pwdencrypt('原始密码') select pwdcompare('原始密码','加密后密码') = 1--相同:否则不相同 3.取回表中字段: declare @list varchar(1000),@sql nvarchar(10

SQL数据库开发中的一些经典代码

  1.按姓氏笔画排序: Select * From TableName Order By CustomerName Collate Chinese_PRC_Stroke_ci_as 2.数据库加密: select encrypt('原始密码') select pwdencrypt('原始密码') select pwdcompare('原始密码','加密后密码') = 1--相同;否则不相同 encrypt('原始密码') select pwdencrypt('原始密码') select pwd

sql怎么避免插入重复数据三种解决方法

第一种方法:设置为主键 第二种方法:设置唯一性约束  代码如下 复制代码 alter table 你的表名 add constraint cons_01 unique (重复列名一,重复列名二,重复列名三,重复列名四,重复列名五) 第三种方法:加SQL语句判断  代码如下 复制代码 if not exists(select 1 from tb where 重复列名一='xx' and 重复列名二='xx' and 重复列名三='xx' and 重复列名四='xx') begin     inse

ado连接sql数据库-ADO的Recordset类的Open方法的用法

问题描述 ADO的Recordset类的Open方法的用法 在MFC里用ADO连接数据库 下面这一句是测试用的,是正确的: m_pAdoRecordset->Open("select UserName from OJUser where UserName = 'admin'",_variant_t((IDispatch *)m_pAdoConnect,true),adOpenDynamic,adLockOptimistic,adCmdText); 但是因为我要根据输入值来获取查询

一段代码示例代码,目前可以兼容odbc 和 OCI 两种连接数据库方法!

odbc|连接数据库|示例 PHP 作的最不好的一点就是为每一种数据库都设计了一种数据库连接方法,这样虽然可以兼容大多数的数据库,但是一旦数据库需要改变,则大事不妙!在这里,我给大家介绍一种我自己的一点心得,希望能够起到抛砖引玉的效果!我的程序代码如下:<? function openConn(){   //打开数据库连接   //ODBC:   //$conn=odbc_connect("dsn","uid","pwd");   //OC