SQL递归查询所有子节点

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL递归查询所有子节点相关的知识,希望对你有一定的参考价值。

一个n层结构的数据表:categories
id: 目录ID,upid: 上级目录ID,name: 目录名称
----------------------------------------
id upid name
----------------------------------------
1 0 中国
2 0 美国
3 1 广东
4 3 深圳
5 2 华盛顿州
6 5 纽约
7 1 上海
......
-----------------------------------------
通过SQL查询出来的结果:
-----------------------------------------
中国 -> 广东 -> 深圳
中国 -> 上海
美国 -> 华盛顿州 -> 纽约
这是道外资企业的试题,原题是英文的,必须用SQL实现,如果广东下面有东莞,是要再从中国开始另起一个分支,大家能给出这种横向结构也行

你这样设计的表用递归来显示最恰当 我刚刚好有这个的代码 发给你参考下吧
/// <summary>
/// 绑定根节点
/// </summary>
/// <param name="id"></param>
/// <param name="ddlList"></param>
public void BindSysMenu(string id, DropDownList ddlList)

ListItem ll = new ListItem();
ll.Text = "╋--请选择-----";
ll.Value = "-1";
ddlList.Items.Add(ll);
DataTable dt = new ManageContentInfoBll().GetWName(id).Tables[0];
foreach (DataRow dr in dt.Rows)

ListItem li = new ListItem();
li.Text = "╋" + dr["W_Name"].ToString();
li.Value = dr["W_ID"].ToString();
ddlList.Items.Add(li);
BindSysMenuChild((dr["W_ID"].ToString()), ddlList, "├—");



/// <summary>
/// 绑定子节点
/// </summary>
public void BindSysMenuChild(string id, DropDownList ddlList, String separtor)

DataTable dt = new ManageContentInfoBll().GetWName(id).Tables[0];
foreach (DataRow dr in dt.Rows)

ListItem li = new ListItem();
li.Text = separtor + dr["W_Name"].ToString();
li.Value = dr["W_ID"].ToString();
string separtor_ = separtor + "——";
ddlList.Items.Add(li);
BindSysMenuChild(dr["W_ID"].ToString(), ddlList, separtor_);



sql 语句 很简单的
select * from WebSubjectMenu where W_Logo ="+id+"
W_Logo 是上级的ID
希望对你有帮助吧。
参考技术A select t1.name as name1, t2.name as name2, t3.name as name3 from categories as t1 left join categories as t2 on t1.id=t2.upid left join categories as t3 on t2.id=t3.upid where t1.upid=0

这样写有一个缺点 就是你必须知道有几层关系 就套几个表
参考技术B select name from categories start with upid=0
connect by prior id =upid
这样应该会显示:
中国
广东
深圳
上海
美国
华盛顿州
纽约

感觉你的设计有点小问题。如果广东下面再来个东莞,你显示成啥样?还从中国开始,重新起一个分支吗?
最好还是不要通过sql查出横向的结果来。
直接纵向查出来,后续处理时,根据需要显示成树或者别的格式即可。
参考技术C 你这样设计的表用递归来显示最恰当
我刚刚好有这个的代码
发给你参考下吧
///
<summary>
///
绑定根节点
///
</summary>
///
<param
name="id"></param>
///
<param
name="ddlList"></param>
public
void
BindSysMenu(string
id,
DropDownList
ddlList)

ListItem
ll
=
new
ListItem();
ll.Text
=
"╋--请选择-----";
ll.Value
=
"-1";
ddlList.Items.Add(ll);
DataTable
dt
=
new
ManageContentInfoBll().GetWName(id).Tables[0];
foreach
(DataRow
dr
in
dt.Rows)

ListItem
li
=
new
ListItem();
li.Text
=
"╋"
+
dr["W_Name"].ToString();
li.Value
=
dr["W_ID"].ToString();
ddlList.Items.Add(li);
BindSysMenuChild((dr["W_ID"].ToString()),
ddlList,
"├-");


///
<summary>
///
绑定子节点
///
</summary>
public
void
BindSysMenuChild(string
id,
DropDownList
ddlList,
String
separtor)

DataTable
dt
=
new
ManageContentInfoBll().GetWName(id).Tables[0];
foreach
(DataRow
dr
in
dt.Rows)

ListItem
li
=
new
ListItem();
li.Text
=
separtor
+
dr["W_Name"].ToString();
li.Value
=
dr["W_ID"].ToString();
string
separtor_
=
separtor
+
"--";
ddlList.Items.Add(li);
BindSysMenuChild(dr["W_ID"].ToString(),
ddlList,
separtor_);


sql
语句
很简单的
select
*
from
WebSubjectMenu
where
W_Logo
="+id+"
W_Logo
是上级的ID
希望对你有帮助吧。

SQL 语句递归查询 With AS 查找所有子节点

create table #EnterPrise
(
  Department nvarchar(50),--部门名称
  ParentDept nvarchar(50),--上级部门
  DepartManage nvarchar(30)--部门经理
)


insert into #EnterPrise select ‘技术部‘,‘总经办‘,‘Tom‘
insert into #EnterPrise select ‘商务部‘,‘总经办‘,‘Jeffry‘
insert into #EnterPrise select ‘商务一部‘,‘商务部‘,‘ViVi‘
insert into #EnterPrise select ‘商务二部‘,‘商务部‘,‘Peter‘
insert into #EnterPrise select ‘程序组‘,‘技术部‘,‘GiGi‘
insert into #EnterPrise select ‘设计组‘,‘技术部‘,‘yoyo‘
insert into #EnterPrise select ‘专项组‘,‘程序组‘,‘Yue‘
insert into #EnterPrise select ‘总经办‘,‘‘,‘Boss‘


--查询部门经理是Tom的下面的部门名称
;with hgo as
(
   select *,0 as rank from #EnterPrise where DepartManage=‘Tom‘
   union all
   select h.*,h1.rank+1 from #EnterPrise h join hgo h1 on h.ParentDept=h1.Department
)
select * from hgo


/*
Department           ParentDept                DepartManage      rank
--------------- -------------------- ----------------------- -----------
技术部               总经办                    Tom               0
程序组               技术部                    GiGi              1
设计组               技术部                    yoyo              1
专项组               程序组                    Yue               2
*/


--查询部门经理是GiGi的上级部门名称
;with hgo as
(
   select *,0 as rank from #EnterPrise where DepartManage=‘GiGi‘
   union all
   select h.*,h1.rank+1 from #EnterPrise h join hgo h1 on h.Department=h1.ParentDept
)
select * from hgo


/*
Department               ParentDept          DepartManage    rank
-------------------- ----------------------  -----------  -----------
程序组                   技术部                 GiGi           0
技术部                   总经办                 Tom            1
总经办                                          Boss           2
*/

如果递归次数大于100,只需在与cte连接的sql 语句的最后加上option (maxrecursion 0) 即可.默认递归

次数为100,设为0表示没有次数限制. 

以上是关于SQL递归查询所有子节点的主要内容,如果未能解决你的问题,请参考以下文章

sql 知道父节点,查询所有的子节点,运用游标,递归,存储过程

sql 知道父节点,查询所有的子节点,运用游标,递归,存储过程

高手帮忙:sql 里怎样递归判断父节点和子节

T-Sql 递归查询(给定节点查所有父节点所有子节点的方法)

[SQL]T-Sql 递归查询(给定节点查所有父节点所有子节点的方法)

SQL 语句递归查询 With AS 查找所有子节点