对所有下属编写递归函数查询
write recursive function query with all subordinates
我在laravel 9
中有这个功能
private function userDirectSubordinates($user_id, $company_id)
{
return User::select(['users.id', 'users.name as label', 'avatar', 'departments.name as department'])
->join('department_user', 'users.id', '=', 'department_user.user_id')
->join('departments', 'departments.id', '=', 'department_user.department_id')
->where('departments.company_id', $company_id)
->whereIn('users.id', function($query) use($user_id) {
$query->select('user_id')
->from('company_user')
->where('superior_id', $user_id);
})
->get();
}
此功能return id 为$user_id
的用户的直接下属来自所选公司$company_id
。示例:
[
["id" => 880, 'label' => 'User 880', 'avatar' => null, 'department' => 'IT'],
["id" => 41, 'label' => 'User 41', 'avatar' => null, 'department' => 'Finance'],
...
]
我如何制作一个递归函数来从每个用户从 directSubordinates 获取...所有下属。最终数组应如下所示:
[
["id" => 880, 'label' => 'User 880', 'avatar' => null, 'department' => 'IT',
'children' => [
["id" => 32, 'label' => 'User 32', 'avatar' => null, 'department' => 'IT', 'children' => []],
["id" => 56, 'label' => 'User 56', 'avatar' => null, 'department' => 'IT',
'children' => [
["id" => 21, 'label' => 'User 21', 'avatar' => null, 'department' => 'Maintenance', 'children' => []],
["id" => 687, 'label' => 'User 687', 'avatar' => null, 'department' => 'Development',
'children' => [
["id" => 334, 'label' => 'User 334', 'avatar' => null, 'department' => 'Development', 'children' => []],
["id" => 335, 'label' => 'User 335', 'avatar' => null, 'department' => 'Development', 'children' => []],
]
]
],
]
],
],
...
];
大概你正在使用 MySQL 8 和 Laravel 9 这意味着你可以这样做(递归语法):
SQL:
select users.id, users.username as username, departments.name as dept, company_user.superior_id as superior_id
FROM users
INNER JOIN department_user on users.id = department_user.user_id
INNER JOIN departments on departments.id = department_user.department_id
INNER JOIN company_user on company_user.user_id = users.id
WHERE
departments.company_id = 1
AND
users.id IN (
with recursive cte (user_id) as (
select user_id
from company_user
where superior_id = 1
union all
select parent.user_id
from company_user parent
inner join cte
on parent.superior_id = cte.user_id
)
select * from cte
)
就个人而言,我不会为此使用 Laravel 查询构建器(只需使用原始数据)。
你得到的结果是这样的:
请注意父(目标用户)不存在,您应该先获取它。
现在您可以遍历数据并将子项附加到 PHP 中的父项并创建一棵树:
$user = findUserById();
$subordinates = findAllSubordinates();
function buildTree(array &$subordinates, $parentId) {
$branch = array();
foreach ($subordinates as &$subordinate) {
if ($subordinate['superior_id'] == $parentId) {
$children = buildTree($subordinates, $subordinate['id']);
if ($children) {
$subordinate['children'] = $children;
}
$branch[] = $subordinate;
unset($subordinate);
}
}
return $branch;
}
$user['children'] = buildTree($subordinates, $user['id']);
我在laravel 9
中有这个功能private function userDirectSubordinates($user_id, $company_id)
{
return User::select(['users.id', 'users.name as label', 'avatar', 'departments.name as department'])
->join('department_user', 'users.id', '=', 'department_user.user_id')
->join('departments', 'departments.id', '=', 'department_user.department_id')
->where('departments.company_id', $company_id)
->whereIn('users.id', function($query) use($user_id) {
$query->select('user_id')
->from('company_user')
->where('superior_id', $user_id);
})
->get();
}
此功能return id 为$user_id
的用户的直接下属来自所选公司$company_id
。示例:
[
["id" => 880, 'label' => 'User 880', 'avatar' => null, 'department' => 'IT'],
["id" => 41, 'label' => 'User 41', 'avatar' => null, 'department' => 'Finance'],
...
]
我如何制作一个递归函数来从每个用户从 directSubordinates 获取...所有下属。最终数组应如下所示:
[
["id" => 880, 'label' => 'User 880', 'avatar' => null, 'department' => 'IT',
'children' => [
["id" => 32, 'label' => 'User 32', 'avatar' => null, 'department' => 'IT', 'children' => []],
["id" => 56, 'label' => 'User 56', 'avatar' => null, 'department' => 'IT',
'children' => [
["id" => 21, 'label' => 'User 21', 'avatar' => null, 'department' => 'Maintenance', 'children' => []],
["id" => 687, 'label' => 'User 687', 'avatar' => null, 'department' => 'Development',
'children' => [
["id" => 334, 'label' => 'User 334', 'avatar' => null, 'department' => 'Development', 'children' => []],
["id" => 335, 'label' => 'User 335', 'avatar' => null, 'department' => 'Development', 'children' => []],
]
]
],
]
],
],
...
];
大概你正在使用 MySQL 8 和 Laravel 9 这意味着你可以这样做(递归语法):
SQL:
select users.id, users.username as username, departments.name as dept, company_user.superior_id as superior_id
FROM users
INNER JOIN department_user on users.id = department_user.user_id
INNER JOIN departments on departments.id = department_user.department_id
INNER JOIN company_user on company_user.user_id = users.id
WHERE
departments.company_id = 1
AND
users.id IN (
with recursive cte (user_id) as (
select user_id
from company_user
where superior_id = 1
union all
select parent.user_id
from company_user parent
inner join cte
on parent.superior_id = cte.user_id
)
select * from cte
)
就个人而言,我不会为此使用 Laravel 查询构建器(只需使用原始数据)。
你得到的结果是这样的:
请注意父(目标用户)不存在,您应该先获取它。
现在您可以遍历数据并将子项附加到 PHP 中的父项并创建一棵树:
$user = findUserById();
$subordinates = findAllSubordinates();
function buildTree(array &$subordinates, $parentId) {
$branch = array();
foreach ($subordinates as &$subordinate) {
if ($subordinate['superior_id'] == $parentId) {
$children = buildTree($subordinates, $subordinate['id']);
if ($children) {
$subordinate['children'] = $children;
}
$branch[] = $subordinate;
unset($subordinate);
}
}
return $branch;
}
$user['children'] = buildTree($subordinates, $user['id']);