在 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=214
和 id=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/