Laravel 'paginate' 与简单使用 'get()' 相比有不同的有序结果

问题描述 投票:0回答:1

我正在尝试使用此查询来获取数据

$game->teams()->orderByRaw('CASE WHEN position IS NULL THEN 0 ELSE 1 END DESC')->orderBy('position')->with(['user'])->get()

它有正确的结果和命令,

但是当我尝试对其进行分页时,当然是通过将

->get()
替换为
->paginate(15)
,现在数据不正确。

使用

get()
时,前15名中的一些数据在使用
paginate
时不再存在,并且据说,使用
get()
时的结果是不同的,但在
paginate
上,某些项目仍然存在于第2页中。

顺便说一句,我有这个

orderByRaw('CASE WHEN position IS NULL THEN 0 ELSE 1 END DESC')
查询将
null positions
放在最后。

php mysql laravel
1个回答
0
投票

出现您遇到的问题是因为分页方法

->paginate()
可能无法像
->get()
那样保留结果的顺序。分页时,数据库查询经常会被修改,这会影响结果的顺序和一致性。

这是确保分页时顺序一致的解决方案:

1。确保一致的排序: 确保您的 order by 子句在这两种情况下都正确应用。这包括通过额外的唯一标识符(例如

id
)进行排序,以保证分页时的顺序一致。

  1. 使用唯一标识符实现一致排序:在唯一列上添加辅助 order by 子句(例如
    id
    )以保持一致的顺序。

以下是修改查询的方法:

  $game->teams()
    ->orderByRaw('CASE WHEN position IS NULL THEN 0 ELSE 1 END DESC')
    ->orderBy('position')
    ->orderBy('id') // Ensure consistent ordering by adding a unique identifier
    ->with(['user'])
    ->paginate(15);

解释

  • orderByRaw('CASE WHEN position IS NULL THEN 0 ELSE 1 END DESC'):这确保将具有 null
    position
    的条目放置在末尾。
  • orderBy('position'):按
    position
    列对剩余条目进行排序。
  • orderBy('id'):添加此操作可确保如果存在具有相同
    position
    的行,它们将一致地按
    id
    排序,这是唯一的。

其他注意事项

  • 检查模型范围或全局范围:确保在使用

    paginate()
    时不存在可能干扰您的查询的模型范围或全局范围。

  • 调试 SQL 查询:使用 Laravel 的

    toSql()
    方法来调试并查看正在执行的实际 SQL 查询。这可以帮助您了解查询在
    get()
    paginate()
    之间如何变化。

    $sqlQuery = $game->teams() ->orderByRaw('CASE WHEN 位置为 NULL THEN 0 ELSE 1 END DESC') ->orderBy('位置') ->orderBy('id') ->with(['用户']) ->toSql();

dd($sqlQuery); // 调试 SQL 查询

通过确保 order by 子句的应用一致并添加用于附加排序的唯一标识符,您应该能够在

get()
paginate()
之间获得一致的结果。

© www.soinside.com 2019 - 2024. All rights reserved.