在id(UUID)=“...”的行之后获取X行

时间:2018-04-20 13:02:16

标签: mysql

我正在尝试实现基于游标的分页。我想在id为'abcd'的行之后获得X行。 (注意,由于我的主ID列是UUID,因此我无法执行where id > 123之类的操作。)

解决此问题的传统方法是使用LIMIT x OFFSET y,但是如果在用户在页面之间导航时在列表顶部插入新记录,则后续页面中的记录将包含在后续页面中。我需要预防并说“在ID为'F'的行后获得3条记录。

谢谢!

2 个答案:

答案 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 |