mysql - SQL - SELECT ... LIMIT [X] OFFSET [Y] 不包括先前的记录

标签 mysql sql database relational-database

在 MySQL 中,我有一个简单的 SELECT 查询,它根据某些条件(num_likes、num_comments 等)对帖子进行排序。

为了将这些帖子加载到我的应用程序中,我使用 LIMIT 和 OFFSET 来每页显示 n 个帖子。但是,SELECT 查询的结果可能会由于插入新记录而发生更改。因此,以前的结果可能会重新出现在后续页面中。

是否可以防止这种情况发生?

最佳答案

是的,可以避免/防止这种情况发生。一种方法是避免使用 LIMIT m,n (或 LIMIT n OFFSET m),而只使用 **LIMIT n` **,以及上一页上最​​后看到的行中的“保存”值。

可以使用查询中保存的值来获取下一页。

假设此查询返回要显示的第一页行:

  SELECT t.num_likes
       , ...
       , t.id
  ORDER BY t.num_likes DESC, t.id DESC
  LIMIT $pagesize

我们保留最后一行的 id 和 num_likes 值,以供下一个查询使用。对于“下一个”查询,我们使用这些值,如下所示:

  SELECT t.num_likes
       , ...
       , t.id
   FROM mytable t
  WHERE t.num_likes <= :last_seen_num_likes 
    AND (t.num_likes < :last_seem_num_likes OR t.id < :last_seen_id)
  ORDER BY t.num_likes DESC, t.id DESC
  LIMIT $pagesize

例如,如果页面上的最后一行是 num_likes=214id=42,则获取接下来 50 行的查询:

  SELECT t.num_likes
       , ...
       , t.id
   FROM mytable t
  WHERE t.num_likes <= 214
    AND (t.num_likes < 214 OR t.id < 42)
  ORDER BY t.num_likes DESC, t.id DESC
  LIMIT 50

使用这种方法本质上保留了行列表中的位置,即使之前添加了行。我们没有尝试重新计数到相同的位置,而是使用保留值来保留我们在列表中的位置。

如果您想启用“上一页”功能,还可以保留“第一次看到”行中的值,并且您可以运行类似的查询,只需翻转不等式比较的方向即可。

(这并不能解决查询之间行上 num_likes 的值发生变化的问题,从而有效地重新排序列表中的该行。)

关于mysql - SQL - SELECT ... LIMIT [X] OFFSET [Y] 不包括先前的记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31252444/

相关文章:

Mysql 月份数字到月份名称的转换

mysql - 使用 != 而不是 < 时得到错误结果

php - 从选择查询中检索日期数据

android - 在 Termux Android 上连接到 MariaDB 服务器

php - 当主键为 varchar 时,无法从 Laravel 的 Eloquent 中检索列值

mysql - 在 MySQL 中存储配置的最佳方式

MySQL 全文相关性

SQL:查找最大行数

database - 将自定义属性添加到 Firebase Auth

c# - 基于服务的数据库和本地数据库之间的混淆