当前位置: 首页 > 面试题库 >

查询以获取带有子记录的父记录,然后是mysql中的下一个父子记录

茅炯
2023-03-14
问题内容

我的Names数据库表中具有以下格式的数据:

ID  | Name                     | ParentID
1   | Parent 1                 | 0
2   | Parent 2                 | 0
3   | Parent 1 Child 1         | 1
4   | Parent 2 Child 1         | 2
5   | Parent 1 Child 1 Child   | 3
6   | Parent 2 Child 1 Child 1 | 4
7   | Parent 2 Child 1 Child 2 | 4

ParentID列将来自该列的数据ID作为父记录。ParentID带有0值的表示根项目。我需要编写查询以按以下顺序获取数据:

ID  | Name                     | ParentID
1   | Parent 1                 | 0
3   | Parent 1 Child 1         | 1
5   | Parent 1 Child 1 Child   | 3
2   | Parent 2                 | 0
4   | Parent 2 Child 1         | 2    
6   | Parent 2 Child 1 Child 1 | 4
7   | Parent 2 Child 1 Child 2 | 4

我需要得到根记录(与记录ParentID为0),然后是所有childsub- children这根记录,然后获得下根的记录,然后childsub-children在这个根记录等等。


问题答案:

我在这里提出的解决方案使用了物化路径的概念。以下是使用样本数据的实例化路径的示例。我希望它可以帮助您理解物化路径的概念:

+----+--------------------------+----------+------------------+
| ID |           Name           | ParentID | MaterializedPath |
+----+--------------------------+----------+------------------+
|  1 | Parent 1                 |        0 | 1                |
|  2 | Parent 2                 |        0 | 2                |
|  4 | Parent 2 Child 1         |        2 | 2.4              |
|  6 | Parent 2 Child 1 Child 1 |        4 | 2.4.6            |
|  7 | Parent 2 Child 1 Child 2 |        4 | 2.4.7            |
|  3 | Parent 1 Child 1         |        1 | 1.3              |
|  5 | Parent 1 Child 1 Child   |        3 | 1.3.5            |
+----+--------------------------+----------+------------------+

每个节点N都有一个实例化路径,该路径告诉您从​​根节点到该节点的路径N。可以构建连接节点ID的连接。例如,5要从其根节点开始到达节点,请访问node
1,node3和node 5,因此node的5物化路径为1.3.5

巧合的是,您要查找的订单可以通过实现路径来实现。

在前面的示例中,实例化路径是buit连接字符串,但是出于多种原因,我更喜欢二进制连接。

要构建物化路径,您需要以下递归CTE:

CREATE TABLE Tree
(
    ID int NOT NULL CONSTRAINT PK_Tree PRIMARY KEY, 
    Name nvarchar(250) NOT NULL,
    ParentID int NOT NULL,
)

INSERT INTO Tree(ID, Name, ParentID) VALUES
(1, 'Parent 1', 0),
(2, 'Parent 2', 0),
(3, 'Parent 1 Child 1', 1),
(4, 'Parent 2 Child 1', 2),
(5, 'Parent 1 Child 1 Child', 3),
(6, 'Parent 2 Child 1 Child 1', 4),
(7, 'Parent 2 Child 1 Child 2', 4)

GO
WITH T AS
(
    SELECT
        N.ID, N.Name, N.ParentID, CAST(N.ID AS varbinary(512)) AS MaterializedPath
    FROM
        Tree N
    WHERE
        N.ParentID = 0

    UNION ALL

    SELECT
        N.ID, N.Name, N.ParentID, CAST( T.MaterializedPath + CAST(N.ID AS binary(4)) AS varbinary(512) ) AS MaterializedPath
    FROM
        Tree N INNER JOIN T
            ON N.ParentID = T.ID

)
SELECT *
FROM T
ORDER BY T.MaterializedPath

结果:

+----+--------------------------+----------+----------------------------+
| ID |           Name           | ParentID |      MaterializedPath      |
+----+--------------------------+----------+----------------------------+
|  1 | Parent 1                 |        0 | 0x00000001                 |
|  3 | Parent 1 Child 1         |        1 | 0x0000000100000003         |
|  5 | Parent 1 Child 1 Child   |        3 | 0x000000010000000300000005 |
|  2 | Parent 2                 |        0 | 0x00000002                 |
|  4 | Parent 2 Child 1         |        2 | 0x0000000200000004         |
|  6 | Parent 2 Child 1 Child 1 |        4 | 0x000000020000000400000006 |
|  7 | Parent 2 Child 1 Child 2 |        4 | 0x000000020000000400000007 |
+----+--------------------------+----------+----------------------------+

上面的递归CTE从根节点开始。计算根节点的物化路径非常简单,它是节点本身的ID。在下一次迭代中,CTE将根节点与其子节点连接在一起。子节点CN的实例化路径是其父节点的实例化路径与节点PNID的串联CN。随后的迭代在树上向下移动一级,直到到达叶节点为止。



 类似资料:
  • 我在使用zkoss和hibernate时遇到了一个问题 我有两个模型一个是少年信息另一个是学校测量 在学校里,我建立了一种多人的关系 当我进入 SessionFactory SessionFactory=新配置()。configure()。buildSessionFactory(); 会话会话=会话工厂。openSession();一场beginTransaction();列表结果1=会话。cre

  • 问题内容: 这是我的表格和这些表格的数据 表名: 代码 表名: 详细信息 结果表: 我想从代码表中获取所有记录,而对于每个代码,我必须从详细信息表中获取所有行,如果某些代码具有所需的值,如果没有,则为Null 谢谢 问题答案: 听起来您在寻找笛卡尔积: 尽管对于较大的表,笛卡尔乘积相当慢…所以请确保这是您真正想要的。

  • 我有一个父表和子表。父记录已由其他进程插入。我需要添加引用父记录的子记录,例如: 插入CHILD记录时,引用父记录的唯一信息是地址。我需要从父表中获取PARENT_ID,使用子的ADDRESS来设置子的FK。 在hibernate中有没有一种方法可以做到这一点,这样我就不需要通过地址查询父项来将其与子记录一起插入?或者,我是否继续沿着这条路径,按地址查询父对象,然后将父对象传递给子对象?

  • 问题内容: 一个活动有很多参与者。参与者的字段为“状态”。 我需要找到除以下事件以外的所有事件:每个参与者的状态都为“出席”的事件。 我可以找到带有以下AR代码的某些参与者处于“呈现”状态的所有事件: 这样就创建了SQL: 这 几乎 可行。问题是,如果参与者的某行(在范围内 )的状态为“离开”,则该事件仍将被获取,因为至少某些同级记录的状态与其他状态相同而不是“现在”。 我需要确保我正在过滤所有事

  • 问题内容: 假设我有两个表,“父母”和“孩子”。父子关系是一个多对多关系,可通过标准的交叉引用表来实现。 我想查找使用SQL(特别是MS SQL Server的T-SQL; 2005语法可以接受)的给定子集的所有成员所引用的所有Parent记录。 例如,假设我有: List item Parent Alice Parent Bob Child Charlie references Alice, B

  • 问题内容: 我有一个表格,其中有一个父/子关系,其中每个孩子的列数据都需要连接到父母中。 这是一些示例数据,该数据已损坏,因此父记录(Id = 96) 为 NULL 。关系是通过字段进行的: 数据应如下所示: 编辑: 后代级别可以是任何深层次,但深子级后代需要更新为主要的父级 。拿下面的最后两个记录( Id = 100 和 Id = 101 )都链接到97。因为 Id = 97 IS NOT NU