You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP实现可用工人等量分配未完成工作的问题求助

PHP实现工人等量分配未完成工作

现有场景:已通过代码获取到包含2位工人的数组,需要将未完成工作等量分配给每位工人,但当前分配代码会把所有工作都分配给第一位工人,期望实现如2位工人分配4项工作时每人各得2项的效果。

获取可用工人数组代码

if (!isset($array_worker)){
    $array_worker = array();
}

$stmt = $dbh->prepare("SELECT username 
                        FROM group_members 
                        WHERE grp_id = :grp_id 
                        AND statut > 0 
                        AND specification != 2");
$stmt->bindValue(':grp_id', $grp_id);    
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);

foreach ($data as $key => $value){
    if (!in_array($value['username'], $array_worker)){
        array_push($array_worker, $value['username']);
    }
}

问题代码(分配逻辑)

$n = 0;
for ($i = 0; $i < count_worknotdone($grp_id); $i++) {
    if ($n >= count($array_worker)){
        $n = 0;
    }

    $stmt = $dbh->prepare("UPDATE work 
                            SET worker = :worker 
                            WHERE grp_id = :grp_id 
                            AND worker IS NULL"); 
    $stmt->bindValue(':worker ', $array_worker[$n]);
    $stmt->bindValue(':grp_id', $grp_id);
    $stmt->execute();

    $n++;
}       

问题原因

这段代码的核心问题是每次执行UPDATE语句时,会修改所有满足worker IS NULL的记录,第一次循环就把所有未完成工作全部分配给了第一位工人,后续循环没有可更新的记录,导致所有工作都归第一位工人。

解决方法

方法1:修改UPDATE语句,每次只更新一条记录

在UPDATE语句末尾添加LIMIT 1,确保每次循环只分配一项工作:

$n = 0;
$workerCount = count($array_worker);
if ($workerCount === 0) {
    exit; // 无可用工人时直接退出
}
$totalWork = count_worknotdone($grp_id);

for ($i = 0; $i < $totalWork; $i++) {
    $currentWorker = $array_worker[$n % $workerCount]; // 用取模简化循环逻辑

    $stmt = $dbh->prepare("UPDATE work 
                            SET worker = :worker 
                            WHERE grp_id = :grp_id 
                            AND worker IS NULL
                            LIMIT 1"); 
    $stmt->bindValue(':worker', $currentWorker);
    $stmt->bindValue(':grp_id', $grp_id);
    $stmt->execute();

    $n++;
}       

方法2:先获取所有未完成工作ID,再批量分配(更高效)

先一次性取出所有未完成工作的ID,再通过循环逐个分配,减少数据库查询次数:

// 1. 获取所有未完成工作的ID
$stmt = $dbh->prepare("SELECT id FROM work WHERE grp_id = :grp_id AND worker IS NULL");
$stmt->bindValue(':grp_id', $grp_id);
$stmt->execute();
$workIds = $stmt->fetchAll(PDO::FETCH_COLUMN, 0);

$workerCount = count($array_worker);
if ($workerCount === 0 || empty($workIds)) {
    exit;
}

// 2. 循环分配工作
foreach ($workIds as $index => $workId) {
    $currentWorker = $array_worker[$index % $workerCount];
    $stmt = $dbh->prepare("UPDATE work SET worker = :worker WHERE id = :work_id");
    $stmt->bindValue(':worker', $currentWorker);
    $stmt->bindValue(':work_id', $workId);
    $stmt->execute();
}

额外优化:简化工人数组获取逻辑

如果group_members表中username不会重复出现,可以直接用FETCH_COLUMN获取工人数组,省去去重循环:

$stmt = $dbh->prepare("SELECT username 
                        FROM group_members 
                        WHERE grp_id = :grp_id 
                        AND statut > 0 
                        AND specification != 2");
$stmt->bindValue(':grp_id', $grp_id);    
$stmt->execute();
$array_worker = $stmt->fetchAll(PDO::FETCH_COLUMN, 0);

内容的提问来源于stack exchange,提问作者julian goncalves

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 21:20:27