我有一个表格列出了每个元素的父子关系,如下所示:
ParentID ParentTitle ChildId ChildTitle
----------------------------------------------
843 Documents 38737 Jobs
843 Documents 52537 Tools
843 Documents 5763 SecondOps
843 Documents 4651 Materials
38737 Jobs 16619 Job001
38737 Jobs 16620 Job002
38737 Jobs 16621 Job003
38737 Jobs 16622 Job004
38737 Jobs 16623 Job005
52537 Tools 1952 HandTools
52537 Tools 1953 Automated
52537 Tools 1957 Custom
1952 HandTools 12 Cordless10mm
1952 HandTools 13 Cordless8mm
1952 HandTools 14 CableCrimp
1952 HandTools 15 Cutter
1952 HandTools 16 EdgePlane
5763 SecondOps 101 Procedure001
5763 SecondOps 102 Procedure002
5763 SecondOps 103 Procedure003
4651 Materials 33576 Raw
4651 Materials 33577 Mixed
4651 Materials 33578 Hybrid
4651 Materials 33579 Custom
16622 Job004 101 Procedure001
16622 Job004 14 CableCrimp
16622 Job004 15 Cutter
16622 Job004 4651 Mixed
16623 Job005 102 Procedure002
16623 Job005 103 Procedure003
16623 Job005 16619 Job001
16623 Job005 1953 Automated
16623 Job005 33579 Custom
16623 Job005 33576 Raw
我想使用ID获取每个组合的完整路径,例如
Documents\Jobs\Job003 = 843\38737\16621
另一个例子是" Procedure001"列在2个地方
Documents\SecondOps\Procedure001 = 843\5763\101
这里也引用了同一文件:
Documents\Jobs\Job004\Procedure001 = 843\38737\16622\101
我想使用此表并在.NET中构建TreeView。因此,拥有每个项目的完整路径将使它成为一个蛋糕步行。
否则,我想我可以从Root页面开始,继续通过父级递归,构建子列表,然后递归这些,等等。
有没有更好的方法来查询它来构建这些路径?此列表有400,000条记录,因此如果有更有效的方式可以节省时间
这一切都是在AS400系统数据库中直到2000年,然后被制作成MediaWiki网站。我正在通过api提取数据,目的是为SQL Server数据库构建一个接口。
我可以做基本的SQL查询,连接,工会等。
如果不清楚,我可以告诉我其他信息
答案 0 :(得分:1)
如果您使用的是SQL SERVER MS,则可以使用INNER JOIN
和LEFT JOIN
,以下是查询的外观,它将根据您的要求为您提供完整的结果(组合): / p>
SELECT A.ParentTitle + '\'+B.ParentTitle+
CASE WHEN C.ParentTitle IS NOT NULL THEN '\' +C.ParentTitle
ELSE ''
END
+
' =' + A.ParentID + '\'+B.ParentID+
CASE WHEN C.ParentID IS NOT NULL THEN '\' +C.ParentID
ELSE ''
END
FROM TABLE AS A
INNER JOIN TABLE AS B
ON B.ParentID = A.ChildId
LEFT JOIN TABLE AS C
ON C.ParentID = B.ChildId
不是100%确定它是否会像我预期的那样工作,请试一试xD
答案 1 :(得分:1)
树结构意味着通用解决方案的递归。 请不要在sql中尝试这个。只需将sql中的datarow转换为列表或其他类似的东西,然后用编程语言填充递归。
你的树类会像:
public class MyObj {
public int Id {get; set;}
public string Title {get; set;}
public List<MyObj> {get; set; } = null;
}
0.你表示非常错误。核心方式是:
CREATE TABLE Jobs(
Id int not null primary key,
Title nvarchar(255) not null,
StartTime datetime,--optional maybe will help
ParentId int null --can be null root will have no parent
)
但我会尝试在你的桌子上解释它是如何完成的。 我想你有一些类型的datacontext(DBML,EDMX等)
将列出您的根的查询:
SELECT DISTINCT a.ParentId FROM
YourTable a LEFT JOIN
YourTable b ON a.ParentId=b.ChildId
WHERE b.ParentId is null
创建一个递归过程,在上面的类结构中重新检索数据(MyObj)。
过程MyObj GetTree(int id,db){ if(db.YourTable.Any(r =&gt; r.ParentId == Id)){
var q=db.YourTable.Select(r => r.ParentId==Id).ToList();
var result = new MyObj{
Id = q.ParentId,
Title = q.ParentTitle,
Children = new List<MyObj>()
}
foreach( var el in q) {
if (db.YourTable.Any(r => r.ParentId==el.ChildId))
result.Children.Add(GetTree(el.ChildId,db))
else
result.Children.Add( new MyObj{
Id = el.ChildId,
Title = el.ChildTitle,
Children = null
});
return result;
}
}
return null;
}
使用列表中存储的列表ID生成树,让我们说ListIds你会做类似的事情:
List finaltrees = new List()
Ids.ForEach(id => finaltrees.Add(GetTree(id,dbcontext));
现在你在最终树中有了一个树形结构。
PS:
我直接在浏览器中编写代码(C#),可能会出现一些拼写错误。
答案 2 :(得分:0)
因此,要详细说明我要做的事情,我正在使用一个不使用命名空间来建立文档路径的维基版本。
例如,如果页面在文档树上有3层深度,如此
使用命名空间方法Page03的名称(路径)是&#34; RootPage:Page01:Page02:Page03&#34;
我想用PageIDs
做同样的事情所以给出这个例子你会有
所以现在我所要做的就是将PagePath放在一起。
使用此wiki需要考虑几个挑战
要记住的关键点即使页面被列为许多其他页面的子项,也只有一个页面存在,我只需要其中一个页面。
所以在这里使用LONG's example就是我要去的地方
使用此表:
CREATE Table [dbo].[ExampleTable](
[RecordID] Int IDENTITY (1, 1) Not NULL,
[ParentID] Int Not NULL,
[ParentTitle] VARCHAR(800) NULL,
[ChildID] Int Not NULL,
[ChildTitle] VARCHAR(800) NULL,
PRIMARY KEY CLUSTERED ([RecordID] ASC),);
此数据:
INSERT INTO [dbo].[ExampleTable]
([ParentID]
,[ParentTitle]
,[ChildID]
,[ChildTitle])
VALUES
(843,'Documents',38737,'Jobs'),
(843,'Documents',52537,'Tools'),
(843,'Documents',5763,'SecondOps'),
(843,'Documents',4651,'Materials'),
(38737,'Jobs',16619,'Job001'),
(38737,'Jobs',16620,'Job002'),
(38737,'Jobs',16621,'Job003'),
(38737,'Jobs',16622,'Job004'),
(38737,'Jobs',16623,'Job005'),
(52537,'Tools',1952,'HandTools'),
(52537,'Tools',1953,'Automated'),
(52537,'Tools',1957,'Custom'),
(1952,'HandTools',12,'Cordless10mm'),
(1952,'HandTools',13,'Cordless8mm'),
(1952,'HandTools',14,'CableCrimp'),
(1952,'HandTools',15,'Cutter'),
(1952,'HandTools',16,'EdgePlane'),
(5763,'SecondOps',101,'Procedure001'),
(5763,'SecondOps',102,'Procedure002'),
(5763,'SecondOps',103,'Procedure003'),
(4651,'Materials',33576,'Raw'),
(4651,'Materials',33577,'Mixed'),
(4651,'Materials',33578,'Hybrid'),
(4651,'Materials',33579,'Custom'),
(16622,'Job004',101,'Procedure001'),
(16622,'Job004',14,'CableCrimp'),
(16622,'Job004',15,'Cutter'),
(16622,'Job004',4651,'Mixed'),
(16623,'Job005',102,'Procedure002'),
(16623,'Job005',103,'Procedure003'),
(16623,'Job005',16619,'Job001'),
(16623,'Job005',1953,'Automated'),
(16623,'Job005',33579,'Custom'),
(16623,'Job005',33576,'Raw')
GO
此查询,我从LONG的例子中修改过:
SELECT DISTINCT C.ChildTitle as PageTitle, convert(varchar(20),A.ParentID) + ':' + convert(varchar(20),B.ParentID) +
CASE WHEN C.ParentID IS NOT NULL THEN ':' + convert(varchar(20),C.ParentID)
ELSE ''
END
+
CASE WHEN C.ChildID IS NOT NULL THEN ':' + convert(varchar(20),C.ChildID)
ELSE ''
END
FROM ExampleTable AS A
INNER JOIN ExampleTable AS B
ON B.ParentID = A.ChildId
LEFT JOIN ExampleTable AS C
ON C.ParentID = B.ChildId
ORDER By PageTitle
我得到了这些结果:
PageTitle UnNamed
NULL 16622:4651
NULL 38737:16622
NULL 38737:16623
NULL 52537:1952
NULL 843:38737
NULL 843:4651
NULL 843:52537
NULL 843:5763
Automated 843:38737:16623:1953
CableCrimp 843:38737:16622:14
CableCrimp 843:52537:1952:14
Cordless10mm 843:52537:1952:12
Cordless8mm 843:52537:1952:13
Custom 38737:16622:4651:33579
Custom 843:38737:16623:33579
Cutter 843:38737:16622:15
Cutter 843:52537:1952:15
EdgePlane 843:52537:1952:16
Hybrid 38737:16622:4651:33578
Job001 843:38737:16623:16619
Mixed 38737:16622:4651:33577
Mixed 843:38737:16622:4651
Procedure001 843:38737:16622:101
Procedure002 843:38737:16623:102
Procedure003 843:38737:16623:103
Raw 38737:16622:4651:33576
Raw 843:38737:16623:33576
我想得到的是每个页面的单一出现,不管找到哪个家长
然后我可以使用这些路径将虚拟树结构转换为实际的树结构。
最后一期是实际的链接列表与我创建的示例非常相似,只是它有 400,000条记录。
当我针对实际的&#34;链接列表&#34;运行此查询时它运行大约17分钟,内存不足。
我一直在研究MAXRECURSION选项,但我还在研究它,不知道这是不是问题。