父子孙关系的SQL查询

父子孙关系的SQL查询,sql,sql-server,hierarchical-data,recursive-query,Sql,Sql Server,Hierarchical Data,Recursive Query,我想问一下,任何SQL查询都可以与level建立父子孙关系。另外,我想让孩子跟着他们的父母 我的桌子是这样的 ID |ParentID| ChildID |Type 0048 |50199956|50856732(MB) |Got Child 0049 |50199956|50856711(GA) |Got Child 0050 |50199956|YUIOP-78-OP |No Child ID |ParentID | ChildID |Type 0051|50

我想问一下,任何SQL查询都可以与level建立父子孙关系。另外,我想让孩子跟着他们的父母

我的桌子是这样的

 ID  |ParentID|  ChildID    |Type
0048 |50199956|50856732(MB) |Got Child
0049 |50199956|50856711(GA) |Got Child
0050 |50199956|YUIOP-78-OP  |No Child

ID  |ParentID    |  ChildID    |Type
0051|50856732(MB)|NUYU-IO-OO   |Got Child
0052|50856732(MB)|5085675939   |No Child
0053|50856732(MB)|YRTOP-VG-34  |No Child

ID  |ParentID  |  ChildID  |Type
0122|NUYU-IO-OO|55466789   |No Child
0123|NUYU-IO-OO|34561277   |No Child
0124|NUYU-IO-OO|46796439   |No Child

ID  |ParentID    |  ChildID    |Type
0067 |50856711(GA)|IOP78I-UI-67 |No Child
我想要的结果是:

ID   |ParentID    |ChildID      |Type
0048 |50199956    |50856732(MB) |Got Child
0049 |50856732(MB)|NUYU-IO-OO   |Got Child
0122 |NUYU-IO-OO  |55466789     |No Child
0123 |NUYU-IO-OO  |34561277     |No Child
0124 |NUYU-IO-OO  |46796439     |No Child
0050 |50856732(MB)|5085675939   |No Child
0051 |50856732(MB)|YRTOP-VG-34  |No Child
0067 |50199956    |50856711(GA) |Got Child
0052 |50856711(GA)|IOP78I-UI-67 |No Child
0053 |50199956    |YUIOP-78-OP  |No Child
已编辑
解决了。只需使用CTE递归并在子部分添加ID(varchar50)),然后按ID排序。感谢所有试图帮助我的人^^

我相信这里的诀窍是知道如何按代排序。在这种情况下,对于每一行,您都必须检查它们是顶层、中层还是底层

因为只有三代人,我们可以偷懒,两次联合起来创建一个家庭ID。
COALESCE
让我们默认祖父母一代的ID,但是如果它不存在(即,此行不是孙子),那么它将使用父代的ID,但如果不存在(即,此行不是子代),然后它将使用自己的ID(假定这一行是祖父母)。通过按此ID排序,我们将一行的所有成员分组在一起。然后,在该家族ID中,按ID字段排序,该字段在早期世代中似乎较低

SELECT
a.id
,a.parentID
,a.childID
,COALESCE(c.ID, b.ID, a.ID) as sort_id    --if I have grandparents, sort by them, otherwise sort by my parents, otherwise myself
FROM table a
LEFT JOIN table b ON a.parentID = b.childID  --find my parents
LEFT JOIN table c ON b.parentID = c.childID  --find my grandparents
ORDER BY sort_id, a.id    --taking advantage of the fact that earlier generations have lower ID values

我相信这里的诀窍是知道如何按代排序。在这种情况下,对于每一行,您都必须检查它们是顶层、中层还是底层

因为只有三代人,我们可以偷懒,两次联合起来创建一个家庭ID。
COALESCE
让我们默认祖父母一代的ID,但是如果它不存在(即,此行不是孙子),那么它将使用父代的ID,但如果不存在(即,此行不是子代),然后它将使用自己的ID(假定这一行是祖父母)。通过按此ID排序,我们将一行的所有成员分组在一起。然后,在该家族ID中,按ID字段排序,该字段在早期世代中似乎较低

SELECT
a.id
,a.parentID
,a.childID
,COALESCE(c.ID, b.ID, a.ID) as sort_id    --if I have grandparents, sort by them, otherwise sort by my parents, otherwise myself
FROM table a
LEFT JOIN table b ON a.parentID = b.childID  --find my parents
LEFT JOIN table c ON b.parentID = c.childID  --find my grandparents
ORDER BY sort_id, a.id    --taking advantage of the fact that earlier generations have lower ID values

带递归CTE的按层次排序路径

with h as(
    -- top level rows, no parent detected
    select cast(ChildID+'>' as varchar(max)) as path, * 
    from MyTable t1
    where not exists( select 1 from MyTable t2 where t1.ParentID = t2.ChildID)
    --
    union all
    select path + t.childID + '>', t.*
    from h
    join MyTable t on h.ChildID = t.ParentID
)
select * 
from h
order by path;

带递归CTE的按层次排序路径

with h as(
    -- top level rows, no parent detected
    select cast(ChildID+'>' as varchar(max)) as path, * 
    from MyTable t1
    where not exists( select 1 from MyTable t2 where t1.ParentID = t2.ChildID)
    --
    union all
    select path + t.childID + '>', t.*
    from h
    join MyTable t on h.ChildID = t.ParentID
)
select * 
from h
order by path;

您正在使用哪些RDBMS?SQL Server 2012您正在使用哪些RDBMS?SQL Server 2012实际上它不仅仅是3级,它还有更多,我只是在上面展示了一些示例。它是一个已知的级别数吗?不。它可能是5级或更多实际上它不仅仅是3级,它有更多,我只是在上面展示了一些例子。这是一个已知的级别数吗?不。可能是5级。看起来像是在递归查询“h”的“路径”列中的锚和递归部分之间有一些错误类型不匹配。请显示DDL。看起来像是在“路径”列中的锚和递归部分之间有一些错误类型不匹配递归查询的“h”显示您的DDL请。