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

Codeigniter limit offset实现降序分页返回空结果问题排查

问题根因

你代码的核心错误是混淆了SQL LIMIT 偏移量和数据ID值的定义:
MySQL 中 LIMIT offset, row_count 语法的第一个参数 offset 指的是从结果集的第 offset + 1 行开始返回数据,不是你以为的「筛选ID小于等于offset的记录」。
你首次查询传入index=10作为偏移量,生成的SQL为LIMIT 10, 5,但你的表总共只有10条数据,排序后的结果集行号范围是0~9,从第11行(偏移量10)开始取数据自然返回空结果。

解决方案

这里提供两种常用的分页实现方式,你可以根据业务场景选择:

方案1:传统页码分页

适合需要展示总页数、支持跳转到指定页的场景,不需要提前查询最大ID:

$limit = 5;
// 前端传入当前页码,默认第1页
$current_page = (int)$this->input->get('page', 1);
// 计算偏移量:(页码-1)*每页数量
$offset = ($current_page - 1) * $limit;

$this->db->select('*');
$this->db->from('participant_videos');
$this->db->order_by('id','DESC');
$this->db->limit($limit, $offset);
$query = $this->db->get();
$videos = $query->result_array();

return [
    'videos' => $videos,
    // 告知前端是否还有下一页
    'has_next' => count($videos) === $limit
];
  • 第1页查询偏移量为0,返回ID 10、9、8、7、6
  • 第2页查询偏移量为5,返回ID 5、4、3、2、1
  • 第3页查询返回空,加载结束

方案2:游标分页(推荐用于无限下拉场景)

适合移动端/短视频类的无限下拉加载场景,性能优于传统offset分页,不需要传页码,每次仅需传入上次返回的最小ID:

$limit = 5;
// 前端传入上次返回的列表最小ID,首次查询传0即可
$last_min_id = (int)$this->input->get('last_id', 0);

$this->db->select('*');
$this->db->from('participant_videos');
// 非首次查询时,只筛选ID小于上次最小ID的记录
if ($last_min_id > 0) {
    $this->db->where('id <', $last_min_id);
}
$this->db->order_by('id','DESC');
$this->db->limit($limit);
$query = $this->db->get();
$videos = $query->result_array();

// 计算下次查询需要传入的游标:当前返回列表的最小ID
$next_last_id = empty($videos) ? 0 : end($videos)['id'];

return [
    'videos' => $videos,
    'last_id' => $next_last_id
];
  • 首次查询返回ID 10、9、8、7、6,返回last_id=6
  • 第二次查询传入last_id=6,返回ID 5、4、3、2、1,返回last_id=1
  • 第三次查询传入last_id=1,返回空数组,加载结束

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 22:39:03