我在为 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
)
);
表结构
我相信您所需要的只是添加行号计算,然后有条件地连接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