我将在序言中说我对cte语句完全不熟悉。
我有2个表项表和链接表。链接器表包含关系的父ID和子ID。 我已经看到很多关于如何使用我认为称为关联系统遍历树的示例,其中父ID存储在子记录而不是桥表中。但我似乎无法根据我的情况推断出这一点。 我相信我需要有这样的桥牌表,因为任何一个项目都可能有多个父母,每个父母很可能有多个孩子。
我一起攻击了我自己遍历树的方式,但它是在另一种语言中,xojo,我真的不喜欢它的结果。基本上我每次使用递归函数挖掘每棵树,并在每次需要孩子时查询数据库。
现在我正在尝试创建一个执行相同操作的cte语句。将后代命令保持在父母之下并不是一件大事。
所以我创建了一个示例数据库和其他材料来描述我的问题:
此图表直观地显示了这些关系: diagram
这是我想从数据库返回的内容(某些项目显示在多个位置:
1 : Audio
2 : Speaker
3 : Microphone
4 : Mic Pack
3 : Microphone
5 : Di
6 : Passive Di
11 : Rapco Di
13 : Dbx Di
7 : Lighting
9 : Safety
12 : Small Safety
8 : Rigging
10 : Light Rigging
9 : Safety
12 : Small Safety
示例表:
CREATE TABLE items
(id
INTEGER,name
TEXT,PRIMARY KEY(id
));
CREATE TABLE `linker` ( `parent` INTEGER, `child` INTEGER, PRIMARY KEY(`parent`,`child`) );
Insert Into items(id, name) Values(1, 'Audio');
Insert Into items(id, name) Values(2, 'Speaker');
Insert Into items(id, name) Values(3, 'Microphone');
Insert Into items(id, name) Values(4, 'Mic Pack');
Insert Into items(id, name) Values(5, 'Di');
Insert Into items(id, name) Values(6, 'Passive Di');
Insert Into items(id, name) Values(7, 'Lighting');
Insert Into items(id, name) Values(8, 'Rigging');
Insert Into items(id, name) Values(9, 'Safety');
Insert Into items(id, name) Values(10, 'Lighting Rigging');
Insert Into items(id, name) Values(11, 'Rapco Di');
Insert Into items(id, name) Values(12, 'Small Safety');
Insert Into items(id, name) Values(13, 'Dbx Di');
Insert Into linker(parent, child) Values(1, 2);
Insert Into linker(parent, child) Values(1, 4);
Insert Into linker(parent, child) Values(1, 3);
Insert Into linker(parent, child) Values(4, 3);
Insert Into linker(parent, child) Values(4, 5);
Insert Into linker(parent, child) Values(5, 6);
Insert Into linker(parent, child) Values(6, 11);
Insert Into linker(parent, child) Values(6, 13);
Insert Into linker(parent, child) Values(7, 9);
Insert Into linker(parent, child) Values(9, 12);
Insert Into linker(parent, child) Values(8, 10);
Insert Into linker(parent, child) Values(10, 9);
这是我提出的cte,我相信它是最接近的,但它可能仍然相当遥远:
with cte As
(
Select
id,
name,
0 as level,
Cast(name as varchar(255) as sort
From items i
Left outer Join
linker li
On i.id = li.child
And li.parent is Null
Union All
Select
id,
name,
cte.level + 1,
Cast(cte.sort + '.' + i.name As Varchar(255)) as sort
From cte
Left Outer Join linker li
on li.child = cte.id
Inner Join items i
On li.parent = i.id
)
Select
id,
name,
level,
sort
From cte
Order By Sort;
提前感谢您的帮助。我非常乐观地认为我从数据结构中所做的一切都是错误的,所以在你回答时请记住这一点。
编辑:可能值得注意的是,结果不需要整齐。我计划在cte语句中创建一个祖先路径字段,并使用该patb填充我的树。
编辑:oops,我复制并粘贴了错误的cte代码。我在移动设备上,所以我尽力将其更改为我在桌面上所做的事情。一旦我有机会,我会仔细检查我的笔记的cte声明。
答案 0 :(得分:1)
我的cte声明是:
with cte As(
Select
id,
name,
li.parent,
li.child,
Cast(name as Varchar(255)) as ancestory
From items i
Left Outer Join linker li
On i.id = li.child
Where li.parent is null
Union All
Select
i.id,
i.name,
li.parent,
li.child,
Cast(cte.ancestory || "." || i.name as Varchar(100)) as ancestory
From cte
Left join linker li
On cte.id = li.parent
Inner Join items i
On li.child = i.id
)
select * from cte
结果如下:
id name parent child ancestory
1 Audio Audio
7 Lighting Lighting
8 Rigging Rigging
2 Speaker 1 2 Audio.Speaker
3 Microphone 1 3 Audio.Microphone
4 Mic Pack 1 4 Audio.Mic Pack
9 Safety 7 9 Lighting.Safety
10 Lighting 8 10 Rigging.Lighting Rigging
Rigging
3 Microphone 4 3 Audio.Mic Pack.Microphone
5 Di 4 5 Audio.Mic Pack.Di
12 Small 9 12 Lighting.Safety.Small Safety
Safety
9 Safety 10 9 Rigging.Lighting Rigging.Safety
6 Passive Di 5 6 Audio.Mic Pack.Di.Passive Di
12 Small Safety 9 12 Rigging.Lighting Rigging.Safety.Small Safety
11 Rapco Di 6 11 Audio.Mic Pack.Di.Passive Di.Rapco Di
13 Dbx Di 6 13 Audio.Mic Pack.Di.Passive Di.Dbx Di