打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
树形结构表查询

/*
标题:SQL SERVER 2005中查询指定节点及其所有父节点的方法(表格形式显示)
作者:爱新觉罗·毓华(十八年风雨,守得冰山雪莲花开) 
时间:2010-02-02
地点:新疆乌鲁木齐
*/

create table tb(id varchar(3) , pid varchar(3) , name nvarchar(10))
insert into tb values('001' , null  , N'广东省')
insert into tb values('002' , '001' , N'广州市')
insert into tb values('003' , '001' , N'深圳市')
insert into tb values('004' , '002' , N'天河区')
insert into tb values('005' , '003' , N'罗湖区')
insert into tb values('006' , '003' , N'福田区')
insert into tb values('007' , '003' , N'宝安区')
insert into tb values('008' , '007' , N'西乡镇')
insert into tb values('009' , '007' , N'龙华镇')
insert into tb values('010' , '007' , N'松岗镇')
go

DECLARE @ID VARCHAR(3)

--查询ID = '001'的所有父节点
SET @ID = '001'
;WITH T AS
(
  SELECT ID , PID , NAME 
  FROM TB
  WHERE ID = @ID
  UNION ALL
  SELECT A.ID , A.PID , A.NAME 
  FROM TB AS A JOIN T AS B ON A.ID = B.PID
)
SELECT * FROM T ORDER BY ID
/*
ID   PID  NAME
---- ---- ----------
001  NULL 广东省

(1 行受影响)
*/

--查询ID = '002'的所有父节点
SET @ID = '002'
;WITH T AS
(
  SELECT ID , PID , NAME 
  FROM TB
  WHERE ID = @ID
  UNION ALL
  SELECT A.ID , A.PID , A.NAME 
  FROM TB AS A JOIN T AS B ON A.ID = B.PID
)
SELECT * FROM T ORDER BY ID
/*
ID   PID  NAME
---- ---- ----------
001  NULL 广东省
002  001  广州市

(2 行受影响)
*/

--查询ID = '003'的所有父节点
SET @ID = '003'
;WITH T AS
(
  SELECT ID , PID , NAME 
  FROM TB
  WHERE ID = @ID
  UNION ALL
  SELECT A.ID , A.PID , A.NAME 
  FROM TB AS A JOIN T AS B ON A.ID = B.PID
)
SELECT * FROM T ORDER BY ID
/*
ID   PID  NAME
---- ---- ----------
001  NULL 广东省
003  001  深圳市

(2 行受影响)
*/

--查询ID = '009'的所有父节点
SET @ID = '009'
;WITH T AS
(
  SELECT ID , PID , NAME 
  FROM TB
  WHERE ID = @ID
  UNION ALL
  SELECT A.ID , A.PID , A.NAME 
  FROM TB AS A JOIN T AS B ON A.ID = B.PID
)
SELECT * FROM T ORDER BY ID
/*
ID   PID  NAME
---- ---- ----------
001  NULL 广东省
003  001  深圳市
007  003  宝安区
009  007  龙华镇

(4 行受影响)
*/

drop table tb

--注:除ID值不一样外,四个SQL语句是一样的。


/*
标题:SQL SERVER 2005中查询指定节点及其所有父节点的方法(字符串形式显示)
作者:爱新觉罗·毓华(十八年风雨,守得冰山雪莲花开) 
时间:2010-02-02
地点:新疆乌鲁木齐
*/

create table tb(id varchar(3) , pid varchar(3) , name nvarchar(10))
insert into tb values('001' , null  , N'广东省')
insert into tb values('002' , '001' , N'广州市')
insert into tb values('003' , '001' , N'深圳市')
insert into tb values('004' , '002' , N'天河区')
insert into tb values('005' , '003' , N'罗湖区')
insert into tb values('006' , '003' , N'福田区')
insert into tb values('007' , '003' , N'宝安区')
insert into tb values('008' , '007' , N'西乡镇')
insert into tb values('009' , '007' , N'龙华镇')
insert into tb values('010' , '007' , N'松岗镇')
go

;with t as
(
    select id , pid = id from tb 
    union all
    select t.id , pid = tb.pid from t inner join tb on t.pid = tb.id
select id , 
       [路径(从父到子)] = STUFF((SELECT ',' + pid FROM t WHERE id = tb.id order by t.id , t.pid FOR XML PATH('')) , 1 , 1 , ''),
       [路径(从子到父)] = STUFF((SELECT ',' + pid FROM t WHERE id = tb.id FOR XML PATH('')) , 1 , 1 , '')
from tb
group by id
order by id
/*
id   路径(从父到子)   路径(从子到父)
---- ---------------  ---------------
001  001              001
002  001,002          002,001
003  001,003          003,001
004  001,002,004      004,002,001
005  001,003,005      005,003,001
006  001,003,006      006,003,001
007  001,003,007      007,003,001
008  001,003,007,008  008,007,003,001
009  001,003,007,009  009,007,003,001
010  001,003,007,010  010,007,003,001

(10 行受影响)
*/


;with t as
(
    select id , name , pid = id , path = cast(name as nvarchar(100)) from tb 
    union all
    select t.id , t.name , pid = tb.pid , path = cast(tb.name as nvarchar(100)) from t join tb on tb.id = t.pid 
)
select id , 
       name ,
       [路径(从父到子)_1] = pid1, 
       [路径(从父到子)_2] = reverse(substring(reverse(path1) , charindex(',' , reverse(path1)) + 1 , len(path1))) ,
       [路径(从子到父)_1] = pid2,
       [路径(从子到父)_2] = substring(path2 , charindex(',' , path2) + 1 , len(path2)) from
(
select id , name ,
       pid1 = STUFF((SELECT ',' + pid FROM t WHERE id = tb.id order by t.id , t.pid FOR XML PATH('')) , 1 , 1 , ''),
       pid2 = STUFF((SELECT ',' + pid FROM t WHERE id = tb.id FOR XML PATH('')) , 1 , 1 , ''),
       path1 = STUFF((SELECT ',' + path FROM t WHERE id = tb.id order by t.id , t.pid FOR XML PATH('')) , 1 , 1 , ''),
       path2 = STUFF((SELECT ',' + path FROM t WHERE id = tb.id FOR XML PATH('')) , 1 , 1 , '')
from tb
group by id , name
) m
order by id
/*
id   name    路径(从父到子)_1  路径(从父到子)_2             路径(从子到父)_1  路径(从子到父)_2
---- ------  ----------------  ---------------------------  ----------------  ---------------------------
001  广东省  001               广东省                       001               广东省
002  广州市  001,002           广东省,广州市                002,001           广州市,广东省
003  深圳市  001,003           广东省,深圳市                003,001           深圳市,广东省
004  天河区  001,002,004       广东省,广州市,天河区         004,002,001       天河区,广州市,广东省
005  罗湖区  001,003,005       广东省,深圳市,罗湖区         005,003,001       罗湖区,深圳市,广东省
006  福田区  001,003,006       广东省,深圳市,福田区         006,003,001       福田区,深圳市,广东省
007  宝安区  001,003,007       广东省,深圳市,宝安区         007,003,001       宝安区,深圳市,广东省
008  西乡镇  001,003,007,008   广东省,深圳市,宝安区,西乡镇  008,007,003,001   西乡镇,宝安区,深圳市,广东省
009  龙华镇  001,003,007,009   广东省,深圳市,宝安区,龙华镇  009,007,003,001   龙华镇,宝安区,深圳市,广东省
010  松岗镇  001,003,007,010   广东省,深圳市,宝安区,松岗镇  010,007,003,001   松岗镇,宝安区,深圳市,广东省

(10 行受影响)
*/

drop table tb

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
SQL Server根据子节点查询所有父节点的代码示例
mysql 树查询语句
Sql语句里的递归查询
数据库学习笔记
SQL SERVER 2005 中使用for xml path('')和stuff合并显示多行数据到一行中
【长安联播】广东省深圳市宝安区西乡街道综治中心
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服