如何建立一个SQL查询来构建一个树?

时间:2012-08-23 16:29:19

标签: sql ms-access ado.net treeview

  

可能重复:
  How to store directory / hierarchy / tree structure in the database?

我使用此查询:

SELECT Id, Name, ParentId
FROM Table_1

然后我使用所有元素构建树。

但是,如果我想构建一个从明确Id开始的树,那么我需要创建一个仅返回此Id的查询以及此Id的所有子项 像这样:

SELECT Id, Name, ParentId
FROM Table_1
WHERE (Id = randomNumber) OR (all possible childs of Id = randomNumber)

请帮我查询一下。

编辑:

这是你如何在Oracle中实现的

SELECT Id, Name, ParentId
FROM table_1
Connect by prior Id = ParentId
Start with Id = randomNumber

我需要MS-Access

4 个答案:

答案 0 :(得分:1)

试试这个,我希望这就是你要找的东西:

DECLARE @ID int

SET @ID = 1;

WITH CTE_Table_1
(
 ID,
 Name,
 ParentID,
 TreeLevel
)
AS(
  SELECT 
   ID,
   Name,
   ParentID,
   0 AS TreeLevel
  FROM Table_1
  WHERE ID = @ID

  UNION ALL

  SELECT 
   T.ID,
   T.Name,
   T.ParentID,
   TreeLevel + 1
  FROM Table_1 T
  INNER JOIN CTE_Table_1 ON CTE_Table_1.ID = T.ParentID
)

SELECT * FROM CTE_Table_1

答案 1 :(得分:0)

您可以将表连接父ID和子ID

SELECT T1.Id, T1.Name, T2.Id, T2.Name
FROM   Table_1 as T1
JOIN   Table_1 as T2 on T1.Id = T2.ParentId

鉴于数据

Id, Name       ParentId
1,  Top,        null
2,  ChildOne,   1
3,  ChildTwo,   1
4,  ChildThree, 1

这会给你一个像

这样的结果
1,   Top,    2, ChildOne
1,   Top,    3, ChildTwo
1,   Top,    4, ChildFour

答案 2 :(得分:0)

你几乎就在那里,这应该可以解决问题

SELECT Id, Name, ParentId 
FROM Table_1 
WHERE (Id = randomNumber) OR (ParentId = randomNumber) 

答案 3 :(得分:0)

正如相关文章所述,单独使用SQL无法做到这一点,但是使用SQL和VBA的组合可以相对容易地完成。

目标是让指定的Id返回该记录及其所有子记录。因此,您只需要一个布尔函数,当行Id是指定祖先的直接后代时,该函数返回true。

您的SQL将是:

SELECT Id, Name, ParentId
FROM Table_1
WHERE IsDescendant(Id, randomNumber);

Access中的VBA功能将是:

Public Function IsDescendant(id As Integer, relative As Integer) As Boolean
    Dim currentID As Variant
    currentID = id

    Do Until IsNull(currentID)
        If (currentID = relative) Then
            IsDescendant = True
            Exit Function
        End If
        currentID = DLookup("ParentId", "Table_1", "Id=" & currentID)
    Loop
    IsDescendant = False
End Function

性能方面,这可能不是最好的,因为我使用了DLookup但是如果有显着的性能提升,我们也可以使用RecordSet个对象。这只是我记下的最快的代码。