Tsql T-SQL如何从T-SQL中的树中获取所有项?
我对t-sql查询有问题 假设我有一个类别树(类别ID) 猫桌Tsql T-SQL如何从T-SQL中的树中获取所有项?,tsql,recursion,Tsql,Recursion,我对t-sql查询有问题 假设我有一个类别树(类别ID) 猫桌 1 | 2-\ | 3-\ 6 | 5 | 4 | ... ... ads_表 ad_ID category_ID 当然,category\u ID列引用了cat\u表中的ID列 问题是,如何从所有类别中获取(递归?)所有广告,其中最顶端的父类别是第一个类别?尝试使用递归公共表表达式,即“CTE”(在SQL Server 2005及更高版本中提供),如下所示: --go through a nested
1
|
2-\
| 3-\
6 | 5
| 4 |
... ...
ads_表
ad_ID
category_ID
当然,category\u ID
列引用了cat\u表中的ID
列
问题是,如何从所有类别中获取(递归?)所有广告,其中最顶端的父类别是第一个类别?尝试使用递归公共表表达式,即“CTE”(在SQL Server 2005及更高版本中提供),如下所示:
--go through a nested table supervisor - user table and display the chain
DECLARE @Contacts table (id varchar(6), first_name varchar(10), reports_to_id varchar(6))
INSERT @Contacts VALUES ('1','Jerome', NULL ) -- tree is as follows:
INSERT @Contacts VALUES ('2','Joe' ,'1') -- 1-Jerome
INSERT @Contacts VALUES ('3','Paul' ,'2') -- / \
INSERT @Contacts VALUES ('4','Jack' ,'3') -- 2-Joe 9-Bill
INSERT @Contacts VALUES ('5','Daniel','3') -- / \ \
INSERT @Contacts VALUES ('6','David' ,'2') -- 3-Paul 6-David 10-Sam
INSERT @Contacts VALUES ('7','Ian' ,'6') -- / \ / \
INSERT @Contacts VALUES ('8','Helen' ,'6') -- 4-Jack 5-Daniel 7-Ian 8-Helen
INSERT @Contacts VALUES ('9','Bill ' ,'1') --
INSERT @Contacts VALUES ('10','Sam' ,'9') --
DECLARE @Root_id char(4)
--get 2 and below
SET @Root_id=2
PRINT '@Root_id='+COALESCE(''''+@Root_id+'''','null')
;WITH StaffTree AS
(
SELECT
c.id, c.first_name, c.reports_to_id, c.reports_to_id as Manager_id, cc.first_name AS Manager_first_name, 1 AS LevelOf
FROM @Contacts c
LEFT OUTER JOIN @Contacts cc ON c.reports_to_id=cc.id
WHERE c.id=@Root_id OR (@Root_id IS NULL AND c.reports_to_id IS NULL)
UNION ALL
SELECT
s.id, s.first_name, s.reports_to_id, t.id, t.first_name, t.LevelOf+1
FROM StaffTree t
INNER JOIN @Contacts s ON t.id=s.reports_to_id
WHERE s.reports_to_id=@Root_id OR @Root_id IS NULL OR t.LevelOf>1
)
SELECT * FROM StaffTree
输出:
@Root_id='2 '
id first_name reports_to_id Manager_id Manager_first_name LevelOf
------ ---------- ------------- ---------- ------------------ -----------
2 Joe 1 1 Jerome 1
3 Paul 2 2 Joe 2
6 David 2 2 Joe 2
7 Ian 6 6 David 3
8 Helen 6 6 David 3
4 Jack 3 3 Paul 3
5 Daniel 3 3 Paul 3
(7 row(s) affected)
更改@Root\u id以获得不同的输出:
@Root_id=null
id first_name reports_to_id Manager_id Manager_first_name LevelOf
------ ---------- ------------- ---------- ------------------ -----------
1 Jerome NULL NULL NULL 1
2 Joe 1 1 Jerome 2
9 Bill 1 1 Jerome 2
10 Sam 9 9 Bill 3
3 Paul 2 2 Joe 3
6 David 2 2 Joe 3
7 Ian 6 6 David 4
8 Helen 6 6 David 4
4 Jack 3 3 Paul 4
5 Daniel 3 3 Paul 4
(10 row(s) affected)
您熟悉SQL Server中的常用表表达式吗?CTE的许多用途之一是进行递归查询 以下是我在这方面找到的最好的文章之一:
有一个选项可以避免在树浏览查询中重复出现。您可以将“路径”列添加到类别树中。它应该包含用一些非数字字符(如斜杠)分隔的每个元素 例如,“ID=4”类别的路径如下所示:“/1/2/3/” 现在,当您将广告表加入类别时,您需要执行以下操作:
select * from ads_table
inner join cat_table on cat_table.ID = ads_table.category_ID
where cat_table.Path like '/1/%'
这就是你的问题
您可以在my文章中阅读有关此主题的更多信息链接说:由于发生内部服务器错误,无法显示该页面。“鼓励指向外部资源的链接,但请在链接周围添加上下文,以便您的其他用户了解它是什么以及为什么存在。请始终引用重要链接中最相关的部分,以防无法访问目标站点或永久脱机。”如果一个孩子有双亲怎么办?@Spivonious这里不是这样,需要一种新的方式来设置表格(在哪里放置对第二位家长的引用?)。对所有人来说:这个解决方案非常适合小的或几乎是静态的树。它需要多一点内存。重组(添加、移动、删除部分树)时,可能需要更新所有相关节点的路径以及该列的所有索引(如果有)。但是您只需要一个简单的查询就可以得到整个层次结构。