获取MySql中的所有子项

获取MySql中的所有子项,mysql,database,Mysql,Database,我已经建立了一个简单的测试数据库,它有两个表。数据库基本上是一系列任务的描述。我现在有两个表格: Task: -Id -Name -Variables 及 如表所示,任务可以有子任务。任务A可以由任务B和任务C组成,这可以更深入,任务C也可以由任务D和任务E组成。这种情况有多严重,最初还不清楚。只是我有一个表来描述一般任务,还有一个表来描述任务之间的关系 subtaskconnector有一个“Order”列,这是因为以正确的顺序检索任务非常重要。在上面的示例中,任务B不能放在任务A前面。因此

我已经建立了一个简单的测试数据库,它有两个表。数据库基本上是一系列任务的描述。我现在有两个表格:

Task:
-Id
-Name
-Variables

如表所示,任务可以有子任务。任务A可以由任务B和任务C组成,这可以更深入,任务C也可以由任务D和任务E组成。这种情况有多严重,最初还不清楚。只是我有一个表来描述一般任务,还有一个表来描述任务之间的关系

subtaskconnector有一个“Order”列,这是因为以正确的顺序检索任务非常重要。在上面的示例中,任务B不能放在任务A前面。因此,在这里,与任务B的关系将是数字0,与任务C的关系将是1。因为D是C的第一个子任务,它的顺序号也将是0,而对于E,它将是1


我在这里的问题是,我如何以正确的顺序获得最低级别上的所有任务?我有一些SQL方面的经验,但老实说,我还不知道我将如何进行这项工作。假设我只需要名称,我需要任务B、D和E的名称,按顺序排列。

这可以通过递归cte(需要mysql 8.0或10.2或更高版本)轻松实现。(在早期版本中,您可能需要一个存储过程或一个复杂的查询,每个深度级别都需要一个连接。)

请注意,您确实需要为组合订单字段提供长度,这会导致在本例中存在最大支持深度100000

在查询中,我从一个特定的根任务id(1)开始;您可以选择不是任何其他任务的子任务的所有任务,但是您必须发明一些东西来指定这些任务的初始顺序,因为数据中没有任何东西可以给出根任务的相对顺序

我假设子任务连接器订单介于0和9999999之间


删除where条件以包括非叶任务,这些任务将显示在其子任务之前。如果非叶任务需要出现在其所有子任务(及其子任务)之后,则需要修改cte以区分联合体两部分中的叶任务和非叶任务,给非叶任务一个顺序,例如“aaaaaa”,并让子任务替换父任务顺序的最后一部分,而不是仅仅添加到父任务中。

这个问题可以使用所需输出的示例,但在其他方面似乎是完整的;我不明白投票结果如何。@ysth对于a,它需要更多的细节,也需要一次尝试。@nbk虽然最少的可重复的例子是理想的,而且肯定会使回答问题更容易,但他们的主要目的是确保问题的说明是完整的(而且他们在这方面并不总是成功)。在这里,它已经像预期的那样完整了。再次尝试,这是在一类问题中,我至少不期望这样;如果你不知道你需要一个递归的cte或者这样一个东西甚至存在,你能做的就是解释这个问题;任何尝试都是毫无意义的。“更新问题,使其只关注一个问题。”在这里毫无意义;这个问题非常集中在一个问题上。非常感谢!这正是我需要的。我对SQL有一些经验,但我不知道这样的递归实际上是可能的。是的,我也不知道这些反对票是什么。。。它说它不是集中在一个问题上,我不知道这是怎么一个太普遍的tbh。我已经投票了,在我测试它之后的第一件事;)对不起,忘了它有一个神秘的否决票。谢谢
SubtaskConnector:
-TaskId
-Order
-SubtaskId
with recursive ordered_tasks (task_id, task_order) as (
    select task.id task_id, cast('' as char(800000)) task_order from task where task.id=1
    union all
    select subtask_connector.subtask_id task_id, concat(task_order,lpad(subtask_connector.ord,8,'0')) task_order
    from ordered_tasks
    join subtask_connector using (task_id)
)
select task.id,task.name,task.variables from ordered_tasks
join task on task.id=ordered_tasks.task_id
where not exists (select 1 from subtask_connector where subtask_connector.task_id=ordered_tasks.task_id)
order by ordered_tasks.task_order;