使用 laravel 查询生成器更新记录排名

Posted

技术标签:

【中文标题】使用 laravel 查询生成器更新记录排名【英文标题】:update records rank with laravel query builder 【发布时间】:2020-08-13 01:17:57 【问题描述】:

所以我使用的是 laravel 5.8,我有一个名为 tasks 的表格

id |  name  | rank
------------------
 1 | task 1 |  4
------------------
 2 | task 2 |  3
------------------
 3 | task 3 |  2
------------------
 4 | task 4 |  1

当我想显示这些任务时,我将它们排序为 ordredBy rank 列(即 unique 列),如果我想更改一项任务的排名,我需要更新所有任务的排名

我想使用这个查询:

UPDATE   tasks
JOIN     (SELECT    t.id,
                @curRank := @curRank + 1 AS rank
      FROM      tasks t
      JOIN      (SELECT @curRank := 0) r
      ORDER BY  t.rank DESC
     ) ranks ON (ranks.id = tasks.id)

SET taks.rank = rank.rank;

所以我从查询中选择了部分:

DB::table('tasks ta')
        ->select(DB::raw('ta.id, @curRank := @curRank + 1 as rank'))
        ->crossJoin(DB::raw('select @curRank : 0 as r'))
        ->orderBy('ta.rank', 'desc');

但我不知道如何在 laravel 查询生成器中使用 select 语句加入更新。

【问题讨论】:

我在这里看不到任何@variables 的需要/目的。 【参考方案1】:

其实你不需要更新所有排名,只需要在currentRankexpectedRank之间更新。

示例:假设您想从任务 1 更新排名,从排名 4 到排名 2。您只需在 currentRank 和 expectedRank 之间移动排名

$expectedRank = 2;
$id = 1;
$task = Task::find($id);

// check if $task->rank != $expectedRank then do this query
$ids = Task::whereBetween('rank', [min($task->rank, $expectedRank), max($task->rank, $expectedRank)])
           ->where("id", "!=", $task->id)
           ->orderBy("rank")
           ->pluck("id");
$task->rank = $expectedRank;
$task->save();

$updates = Task::whereIn("id", $ids)
               ->update([
                  'rank'=> $task->rank > $expectedRank ? DB::raw('rank+1') : DB::raw('rank-1')
               ]);

【讨论】:

我很抱歉我迟到的互联网问题:(,感谢您帮助我解决这个问题。我之前尝试过类似的方法,但问题是rank 列是unique 列如果我运行这种逻辑,我最终会遇到重复条目约束。所以如果我执行以下操作:用符号或其他东西更新当前任务等级,然后更新所有其他任务,然后更新(第二次)当前具有适当等级的任务..这是不好的做法吗? 我认为这很糟糕。因为如果你这样做了,你将对你的数据库进行 3 次更新事务处理,我认为可以通过在$updates 中做一些棘手的事情来解决它,尝试在更新中使用 if else 条件来检查它是否是你想要的 ID更新与否。并删除where("id", "!=", $task->id)

以上是关于使用 laravel 查询生成器更新记录排名的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 使用按 id 搜索的查询生成器有线行为

Laravel 查询生成器。返回嵌套结构化数据

Laravel 自定义分页

Laravel 查询构建器 - 查询不工作但在 SQL 控制台中工作

Laravel 使用查询生成器进行嵌套连接查询

使用 laravel 查询生成器嵌套选择?