【问题标题】:How to get the nested child data in SQL Server如何在 SQL Server 中获取嵌套的子数据
【发布时间】:2016-04-14 01:07:00
【问题描述】:

我有两张表如下:

表1:

SectionID SectionName 
 1        ParentSection1
 2        ChildSection1
 3        ChildSection2
 4        ChildChildSection1

表2:

DependentID ParentID ChildID
1           1        2
2           1        3
3           2        4

输出:

ParentId ParentSectionName    ChildSectionName
1        ParentSection1       ChildSection1
1        ParentSection1       ChildSection2
1        ParentSection1       ChildChildSection1

座右铭是将父部分作为子部分的子层次结构。

到目前为止我做了什么:

Select 
    t.Section as ParentID,t.SectionName as ParentSection, 
    c.SectionName as ChildSection 
from 
    Table1 t 
join 
    Table2 d on t.SectionID = d.ParentID 
right join
    c.Table1 on c.SectionID = d.ChildID 
where 
    t.SectionID = 1

SQL 或 Linq 都会有所帮助。请帮帮我。

谢谢

【问题讨论】:

    标签: sql sql-server linq tsql linq-to-sql


    【解决方案1】:

    如果我猜对了,您正在 sql 中寻找树,您需要获取任何叶子到根的路径或与树相关的任何其他任务。
    我建议使用 Adjacency List ModelNested Set Model 代替这种模型来处理 SQL 中的树形数据。
    两者都有优点和缺点。 Here 您可以找到有关它们的详细信息以及它们的实际 SQL 用法。
    如果你选择其中任何一个,你可以删除你的第二张表并处理只有一张表的情况,不需要复杂的SQL查询(确实有这两个模型,会有复杂的查询也一样,但不像您在当前模型中需要的那样多余)。
    假设您选择了嵌套集模型(您可以在此处阅读 Wiki:nested set model in wiki),您的表定义将是:

    SectionID      SectionName           lft    rgt
    ---------      -----------           ---    ---
     1             ParentSection1
     2             ChildSection1
     3             ChildSection2
     4             ChildChildSection1
    

    您需要为左右列设置适当的值(有一个规则可以找出所有叶子的值,不要随意输入它们 - 您需要阅读上面给出的链接中的嵌套集合理论),当您这样做时,您可以通过已经编写的 SQL 查询找到两个叶子之间的任何路径,或者您可以找到您想要的任何叶子的任何根或祖先的所有后代。

    【讨论】:

      【解决方案2】:

      作为 SQL 解决方案,您可以使用recursive Common Table Expression

      CREATE TABLE Table1(SectionID INT, SectionName VARCHAR(50));
      INSERT INTO Table1(SectionID, SectionName )
      VALUES
      ( 1,        'ParentSection1'),
       (2 ,       'ChildSection1'),
       (3  ,      'ChildSection2'),
       (4   ,     'ChildChildSection1');
      
      CREATE TABLE Table2(DependentID INT, ParentID INT,    ChildID INT);
      
      INSERT INTO Table2(DependentID, ParentID, ChildID)
      VALUES
      (1,           1        ,2),
      (2,           1        ,3),
      (3,           2        ,4)
      
      ;with cte (ParentId2, ChildID2, TopLevelParentID) as 
      (
          select  ParentID, ChildID, ParentID as TopLevelParentID
          from    Table2 as t
          -- this is anchor condition, selects top level parents, those who aren't anyone's child
          where   ParentID not in (select distinct ChildID from Table2)
          union all
          select  ParentID, ChildID, cte.TopLevelParentID
          from    Table2 as t
          inner join cte 
          on      cte.ChildID2 = t.ParentId
      )
      
      select  TopLevelParentID as ParentId
              , tParent.SectionName as ParentSectionName
              , tChild.SectionName as ChildSectionName
      from    cte
      inner join Table1 as tParent
      on      tParent.SectionID = cte.TopLevelParentID
      inner join Table1 as tChild
      on      tChild.SectionID = cte.ChildID2
      

      【讨论】:

        【解决方案3】:

        如果您需要从具有任意层数的树中获取数据,您应该使用递归 SQL 语句。用谷歌搜索这个例子应该很容易。 :)

        【讨论】:

        • 添加一些细节:您可以使用带有联合的临时表创建递归 SQL 语句。
        • 如果我希望它是一个 linq 语句,那么呢? :(
        • 不知道。也许尝试与 SQL 相同的方法?否则,您总是可以只提取相关数据并将其组织到您的代码中。
        • 也许找到一个 SQL to Linq 工具?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-01
        • 1970-01-01
        • 2015-02-14
        • 2021-01-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多