当前位置: 首页 > 知识库问答 >
问题:

基于条件不同值的Laravel质量更新

陶福
2023-03-14

我的表格结构如下:

id    //primary_key
value
changed_value    //on update value column should not be updated instead changed value should be updated
status    // 0 - default, 1- updated
am_id  //foreign_key

现在,要进行大规模更新,我将执行以下操作:

Model::where('am_id',$request->am_id)
        ->where('value',$request->value)
        ->update([
                         'changed_value' => '$request->value',
                         'status' => 1
                ]);

但是,我们不应该盲目地将状态设置为1,因为有一个条件。如果value列的值等于$请求,则为-

最初,在插入第一行之后

+-----+-------+---------------+--------+-------+
| id  | value | changed_value | status | am_id |
+-----+-------+---------------+--------+-------+
|  1  | 20    | null          | 0      | 1     |  
+-----+-------+---------------+--------+-------+

第一次更新后

+-----+-------+---------------+--------+-------+
| id  | value | changed_value | status | am_id |
+-----+-------+---------------+--------+-------+
|  1  | 20    | 40            | 1      | 1     |   // changed_value - 40 , status 1
+-----+-------+---------------+--------+-------+

第二次更新后(假设值更新为20),在这种情况下,作为value==changed_value,状态应该更新为0而不是1

+-----+-------+---------------+--------+-------+
| id  | value | changed_value | status | am_id |
+-----+-------+---------------+--------+-------+
|  1  | 20    | 20            | 0      | 1     |     // changed_value - 20 , status 0
+-----+-------+---------------+--------+-------+

这意味着,在下面提到的代码中的模型更新期间。我想插入一个条件,if(value==$请求-

Model::where('am_id',$request->am_id)
        ->where('value',$request->value)
        ->update([
                     'changed_value' => '$request->value',
                      'status' => 1
                ]);

共有3个答案

郎宏逸
2023-03-14

不幸的是,Eloquent的设计不是为了用一个查询来处理这种大规模更新(您需要不同的条件)。您必须逐步浏览模型,或者求助于查询生成器。

$models = Model::where('am_id',$request->am_id)->get();

$models->map(function ($model) use ($request) {

    // status
    $status = $model->value === $request->value ? 0 : 1;

    // update model
    $model->update([
        'changed_value' => $request->value,
        'status' => $status
    ]);

    return $model;
});

编辑:在这个页面上有一些查询生成器的想法,可以让您使一些东西可重用,而不是在任何时候编写原始SQL
https://github.com/laravel/ideas/issues/575#issuecomment-300731748

夏祯
2023-03-14

试试这个。

$value = Model::where('am_id',$request->am_id)->first()->value;
if($request->value == $value){
    $status = 1;
}else{
    $status = 0;
}
Model::where('am_id',$request->am_id)
    ->update([
         'changed_value' => '$request->value',
         'status' => $status
    ]);
汪同
2023-03-14

或者,如果性能有问题,您可以始终使用原始sql。

DB::unprepared(' 
    update model 
    set status = case when (changed_value = "'.$request->value.'") then 0 else 1 end 
    and changed_value = "'.$request->value.'" 
    where value = "'.$request->value.'";
')

编辑:您可以通过两个查询和一个子查询来过滤已经更新的行的ID。

// get ids of all matching status 1 but don't execute the query
$matches = Model::select('id')->where('am_id',$request->am_id)->where('value',$request->value)
    ->where('changed_value', $request->value);

// change matching status 1
Model::whereIn('id', $matches)
    ->update([
        'changed_value' => '$request->value',
        'status' => 1
    ]);

// matching not in status 1
Model::where('am_id',$request->am_id)
    ->where('value',$request->value)
    ->where('changed_value', '!=', $request->value)
    ->whereNotIn('id', $matches)
    ->update([
        'changed_value' => '$request->value',
        'status' => 0
    ]);
 类似资料:
  • 问题内容: 嗨,有一种方法可以根据与SELECT语句其余部分不同的条件来执行SUM(total_points),所以我希望每行<= to $ chosentrack的SUM(total_points)吗?但SELECT语句的其余条件必须满足以下条件。我需要将它们全部归还..当我填充一个联赛桌时。 非常感谢您的帮助。 问题答案: 您也可以将总和放在case语句中,在case语句中评估其他条件,然后仅

  • 我有一个表:配置文件表有一个外键和主键。我想更新行基于两个条件。id==1和user=='admin' 如何使用两个参数更新查询使用雄辩。

  • 问题内容: SQL Server2005。我有一个带有ColumnA位,ColumnB int的表 我可以添加默认值,以便如果为1则为15,如果为0则为0? 我知道我可以用扳机做到这一点,但我的老板对扳机存有偏见(他需要扳机敏感性培训)。 问题答案: 如果您的ColumnB只能为15或零,则可以使其成为基于ColumnA的计算列。这是添加新的计算列的代码:

  • 此问题与几天前发布的问题类似,将行从0折叠到0 与前一个问题不同的是,我们如何根据Id折叠那些时间差小于或等于60的行。 例如,使用相同的数据集 这将通过ID计算时差 这将导致如下所示的新列差异 现在只按< code >事件折叠行。身份证明..其中时间差小于或等于60,即< code>diff 正在寻找有关如何创建这种折叠数据集的帮助。提前谢谢。

  • Spring批处理 不知道如何实现这一点,但要求是假设我们有条件A/B: > 如果是A-我必须在表D/E/F中更新/删除/插入 如果是B-我必须更新/删除/插入表G/H/I 该事务应该在单个事务中完成,这意味着在条件a下,我必须完成所有3个表的更新-D、E、F。如果任何表失败,则不应部分完成该事务。 正在考虑分类器复合项编写器,但不确定它是否是单个事务。