使用递归返回具有唯一 ID 的重复零件

问题描述 投票:0回答:1

我在为 SQL 数据库中的部件创建树结构时遇到一个特殊问题。 这是输出的示例,我使用缩进向父母显示孩子:

   uid: 101
   part_id: 1
   parent_part_id: NULL

       - uid: 102
       - part_id: 2
       - parent_part_id: 1

          - uid: 104
          - part_id: 4
          - parent_part_id: 2

             - uid: 106
             - part_id: 5
             - parent_part_id: 4

       - uid: 103
       - part_id: 3
       - parent_part_id: 1

          - uid: 105
          - part_id: 4
          - parent_part_id: 3

             - uid: 106
             - part_id: 5
             - parent_part_id: 4

如果parent_part_id为NULL,它是树的根。

part_id 4 的两个分支在两次出现时具有唯一的 id (uid),因为它们链接到两个不同的父级,而part_id 4、part_id 5 的子级具有相同的 uid,因为它们链接到相同的父级。

由于我现有的系统,我需要将此数据转换为如下所示:

   uid: 101
   part_id: 1
   parent_part_id: NULL

       - uid: 102
       - part_id: 2
       - parent_part_id: 1

          - uid: 104
          - part_id: 4
          - parent_part_id: 2

             - uid: 106
             - part_id: 5
             - parent_part_id: 4

       - uid: 103
       - part_id: 3
       - parent_part_id: 1

          - uid: 105
          - part_id: 4_2
          - parent_part_id: 3

             - uid: 106
             - part_id: 5_2
             - parent_part_id: 4_2

我需要多次出现的part_id,以便在它们后面有一个数字,以便为它们提供进一步的唯一标识符,并需要它们的后续子项更改其parent_part_id以匹配它。这种情况可能会多次出现,例如“part_id 5、part_id 5_2、part_id 5_3 等”,并且子级的数量超过一层深。

如果这可以通过 MySQL 实现,我很乐意通过那里解决它,除非有更好的解决方案来通过 php 操作数据?我已经尝试通过 php 没有成功。

这是我返回数据的 MySQL:

WITH RECURSIVE generation AS (
SELECT part_id,
uid,
parent_part_id,
part_linked_order
FROM test.part_linked
WHERE
uid = 72
UNION ALL
SELECT child.part_id,
child.uid,
child.parent_part_id,
child.part_linked_order
FROM test.part_linked child
JOIN generation g
ON g.part_id = child.parent_part_id
)
SELECT
generation.part_id,
generation.uid,
generation.parent_part_id,
generation.part_linked_order
FROM generation
Order By
part_linked_order ASC;

(我使用part_linked_order来确定在其分支中显示哪些订单零件,但我不认为它与问题相关)

我尝试使用递归循环遍历重复部分的子项以正确连接它们,但到目前为止还没有效果。

这是输出的数组,以便于测试:

$array = array(
  array(
    "uid" => 101,
    "part_id" => 1,
    "parent_part_id" => NULL
  ),
  array(
    "uid" => 102,
    "part_id" => 2,
    "parent_part_id" => 1
  ),
  array(
    "uid" => 104,
    "part_id" => 4,
    "parent_part_id" => 2
  ),
  array(
    "uid" => 106,
    "part_id" => 5,
    "parent_part_id" => 4
  ),
  array(
    "uid" => 103,
    "part_id" => 3,
    "parent_part_id" => 1
  ),
  array(
    "uid" => 105,
    "part_id" => 4,
    "parent_part_id" => 3
  ),
  array(
    "uid" => 106,
    "part_id" => 5,
    "parent_part_id" => 4
  )
);

我想要输出的内容:

$array = array(
  array(
    "uid" => 101,
    "part_id" => 1,
    "parent_part_id" => NULL
  ),
  array(
    "uid" => 102,
    "part_id" => 2,
    "parent_part_id" => 1
  ),
  array(
    "uid" => 104,
    "part_id" => 4,
    "parent_part_id" => 2
  ),
  array(
    "uid" => 106,
    "part_id" => 5,
    "parent_part_id" => 4
  ),
  array(
    "uid" => 103,
    "part_id" => 3,
    "parent_part_id" => 1
  ),
  array(
    "uid" => 105,
    "part_id" => 4_2,
    "parent_part_id" => 3
  ),
  array(
    "uid" => 106,
    "part_id" => 5_2,
    "parent_part_id" => 4_2
  )
);

表结构

  • 主键:uid
  • part_id(字符串),
  • parent_part_id(字符串),
  • part_linked_order(int)
php mysql recursion tree
1个回答
0
投票

我相信您所需要的只是添加行号计算,然后有条件地连接part_id和该行号以获得想要的结果:

WITH RECURSIVE generation AS (
    SELECT part_id
        , uid
        , parent_part_id
    FROM part_linked
    WHERE uid = 72
    
    UNION ALL
    
    SELECT child.part_id
        , child.uid
        , child.parent_part_id
    FROM part_linked child
    JOIN generation g ON g.part_id = child.parent_part_id
    )
SELECT
      case when p_order > 1 then concat(part_id,'_',p_order) else part_id end as part_linked_order
    , part_id
    , uid
    , parent_part_id
FROM (
    SELECT
          generation.part_id
        , generation.uid
        , generation.parent_part_id
        , ROW_NUMBER() OVER (PARTITION BY part_id ORDER BY parent_part_id) p_order
    FROM generation
  ) d
ORDER BY part_linked_order ASC;
部分链接订单 part_id 流体 parent_part_id
1 1 72
2 2 102 1
3 3 103 1
4 4 104 2
4_2 4 105 3
5 5 106 4
5_2 5 106 4
5_3 5 106 4
5_4 5 106 4

看到这个MYsql fiddle

© www.soinside.com 2019 - 2024. All rights reserved.