我的数据库结构如下:
+----+-----------+-----------+
| ID | Name | Parent_ID |
+----+-----------+-----------+
| 1 | 123a | 2 |
| 2 | Microsoft | 3 |
| 3 | Apple | 14 |
| 5 | IBM | 14 |
| 14 | Amazon | NULL |
+----+-----------+-----------+
我想检索具有特定ID的所有子代的数组。
因此,如果我启动ID = 14的函数,我想得到以下结果:
array (size=2)
0 =>
array (size=3)
'orgid' => string '3' (length=1)
'name' => string 'Apple' (length=5)
'parent_id' => string '14' (length=1)
1 =>
array (size=3)
'orgid' => string '5' (length=1)
'name' => string 'IBM' (length=3)
'parent_id' => string '14' (length=2)
这是我到目前为止的代码:
function get_all_children_from_tree($orgparentid, $childrenArray = null)
{
$CI = get_instance();
$CI->load->model('organization/organization_model');
$allChildrenOrgs = $CI->organization_model->getAllChildrenForParent($orgparentid);
if (empty($childrenArray)) {
$childrenArray = [];
}
foreach ($allChildrenOrgs as $org)
{
$org_id = $org->org_id;
$org_name = $org->name;
$org_parent_id = $org->parent_id;
$arr = array('orgid' => $org_id, 'name' => $org_name, 'parent_id' => $org_parent_id);
array_push($childrenArray, $arr);
if (!empty($org_id)) {
get_all_children_from_tree($org_id, $childrenArray);
}
}
return $childrenArray;
}
在第一个子节点上进行深度学习非常有用,并且可以为我提供正确的结果,但是,一旦我输入了根节点的第二个子节点(在此示例中为IBM),结果数组将在递归点处返回其原始值函数被调用。因此,所有孩子都被结果驱逐出境。
例如,上面提供的代码和示例数据的结果将是:
array (size=5)
0 =>
array (size=3)
'orgid' => string '14' (length=1)
'name' => string 'Amazon' (length=6)
'parent_id' => NULL
4 =>
array (size=3)
'orgid' => string '5' (length=1)
'name' => string 'IBM' (length=3)
'parent_id' => string '14' (length=2)
如果您使用的是MySQL 8+,则可以使用递归分层CTE在数据库上完全解决此问题:
WITH RECURSIVE cte (id, name, parent_id) AS (
SELECT ID, Name, Parent_ID
FROM yourTable
WHERE ID = 14
UNION ALL
SELECT t1.ID, t1.Name, t1.Parent_ID
FROM yourTable t1
INNER JOIN cte t2 ON t1.Parent_ID = t2.ID
)
SELECT * FROM cte;
还有一些方法可以在早期版本的MySQL上执行此操作,尽管在任何情况下我都建议您在数据库本身而不是PHP上进行处理。
您是对的,我已决定升级mysql以允许CTE支持。非常感谢 !!无论如何,在SQL中它可能比在PHP中要快得多。