我正在尝试实现基于游标的分页。我想在id为'abcd'的行之后获得X行。 (注意,由于我的主ID列是UUID,因此我无法执行where id > 123
之类的操作。)
解决此问题的传统方法是使用LIMIT x OFFSET y
,但是如果在用户在页面之间导航时在列表顶部插入新记录,则后续页面中的记录将包含在后续页面中。我需要预防并说“在ID为'F'的行后获得3条记录。
谢谢!
答案 0 :(得分:1)
好一点黑客但可能会奏效:
SET @rank=0;
SELECT stuff_to_select FROM (
SELECT @rank:=IF(@rank=0 AND id = 'abcd', 1, @rank) AS rank, stuff_to_select
FROM table
ORDER BY arbitrary_order_by
) t WHERE rank > 0 LIMIT pagesize
这个想法是保持等级0,直到你达到你想要的ID,然后将其切换为1并选择在该切换后发生的所有事情。我确信这种方法有一百万个注意事项,因此请谨慎使用。
另外,您可能已经注意到它从可能较大的结果集中选择了2。
答案 1 :(得分:0)
感谢@apokryfos(以及另一个最初引导我走正确道路的人,但不幸删除了他的回答!),我已经设法将一个可接受的基于游标的分页实例放在一起。
DEMO: http://sqlfiddle.com/#!9/824f28/54/0
<强>架构:强>
CREATE TABLE `test` (
`id` varchar(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`published_at` datetime DEFAULT NULL
);
INSERT INTO `test`
(`id`, `published_at`)
VALUES
('a','2011-02-12 14:53:27'),
('b','2010-05-21 14:53:27'),
('c','2012-03-30 14:53:27'),
('d','2011-09-30 14:53:27'),
('e','2011-08-30 14:53:27'),
('f','2010-09-26 14:53:27'),
('g','2010-05-13 14:53:27'),
('h','2011-04-12 14:53:27'),
('i','2010-12-23 14:53:27');
<强>查询:强>
SELECT id, published_at FROM (
SELECT *, @track:=IF(@track=0 AND id = 'i', @track+1, @track) AS toInclude
FROM `test`
ORDER BY published_at
) a, (SELECT @track:=0) b
WHERE toInclude = 1
ORDER BY published_at
LIMIT 3 OFFSET 1
结果:
| id | published_at |
|-----|----------------------|
| a | 2011-02-12T14:53:27Z |
| h | 2011-04-12T14:53:27Z |
| e | 2011-08-30T14:53:27Z |