使用 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】:其实你不需要更新所有排名,只需要在currentRank和expectedRank之间更新。
示例:假设您想从任务 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 查询生成器更新记录排名的主要内容,如果未能解决你的问题,请参考以下文章