Sql 如何在活动记录作用域中给定记录ID后返回N条记录?

Sql 如何在活动记录作用域中给定记录ID后返回N条记录?,sql,ruby-on-rails,activerecord,ruby-on-rails-4,Sql,Ruby On Rails,Activerecord,Ruby On Rails 4,给定一个活动记录范围,如何在给定记录之后返回N条记录 例如,我们考虑了按人口排序的城市面积的列表: 活动记录范围: Area.ordered_by_population 返回的行: ID | Area ------------ 9 | Tokyo 2 | Jakarta 7 | Seoul 1 | Delhi 8 | Shanghai 4 | Manila 3 | Karachi 5 | New York City 6 | São Paulo 现在我需要在ID 8(上海)之

给定一个活动记录
范围
,如何在给定记录之后返回N条记录

例如,我们考虑了按人口排序的城市面积的列表:

活动记录范围:

Area.ordered_by_population
返回的行:

ID | Area
------------
 9 | Tokyo
 2 | Jakarta
 7 | Seoul
 1 | Delhi
 8 | Shanghai
 4 | Manila
 3 | Karachi
 5 | New York City
 6 | São Paulo
现在我需要在ID 8(上海)之后返回3条下一条记录。因此,结果将是:

4 | Manila
3 | Karachi
5 | New York City
rails调用将如下所示:

Area.ordered_by_population.records_after_id(id: 8, count: 3)
那么,如何在id之后编写这个
记录
方法呢

性能要求:该方法应处理具有100K记录的db表,并且速度相对较快(在现代笔记本电脑上,我的目标是1ms)

更新
比灵顿指出了这个问题的重要细微差别。不幸的是,我不能使用分页解决方案。我需要在给定记录之后返回行。它必须是相对于记录的。

我可能误解了这个问题,但听起来您想要的是分页,而实际上您并不关心ID。我过去成功地使用了。您也可以在没有gem的情况下通过更改查询中的
限制
偏移量
来实现这一点,但是gem使管理这一点更加用户友好

与卡米纳里:

Area.ordered_by_population.page(1).per(8)
Area.ordered_by_population.page(2).per(8)
Area.ordered_by_population.page(3).per(8)
Area.ordered_by_population.limit(10).offset(0)
Area.ordered_by_population.limit(10).offset(10)
Area.ordered_by_population.limit(10).offset(20)
没有卡米纳里:

Area.ordered_by_population.page(1).per(8)
Area.ordered_by_population.page(2).per(8)
Area.ordered_by_population.page(3).per(8)
Area.ordered_by_population.limit(10).offset(0)
Area.ordered_by_population.limit(10).offset(10)
Area.ordered_by_population.limit(10).offset(20)

我可能误解了这个问题,但听起来你想要的是分页,而你实际上并不关心ID。我过去成功地使用了。您也可以在没有gem的情况下通过更改查询中的
限制
偏移量
来实现这一点,但是gem使管理这一点更加用户友好

与卡米纳里:

Area.ordered_by_population.page(1).per(8)
Area.ordered_by_population.page(2).per(8)
Area.ordered_by_population.page(3).per(8)
Area.ordered_by_population.limit(10).offset(0)
Area.ordered_by_population.limit(10).offset(10)
Area.ordered_by_population.limit(10).offset(20)
没有卡米纳里:

Area.ordered_by_population.page(1).per(8)
Area.ordered_by_population.page(2).per(8)
Area.ordered_by_population.page(3).per(8)
Area.ordered_by_population.limit(10).offset(0)
Area.ordered_by_population.limit(10).offset(10)
Area.ordered_by_population.limit(10).offset(20)

records\u after\u id
方法可以定义如下

    module Pager
      def records_after_id(id:, count:)
        relation = self.dup
        # perform the query and find the index of the id
        offset = relation.pluck(:id).find_index(id)
        # OFFSET LIMIT query starting +1 after the found id
        relation.offset(offset + 1).limit(count)
      end
    end
    Area.ordered_by_population.extending(Pager).records_after_id(id: 8, count: 3)
那么你可以这样称呼它

    module Pager
      def records_after_id(id:, count:)
        relation = self.dup
        # perform the query and find the index of the id
        offset = relation.pluck(:id).find_index(id)
        # OFFSET LIMIT query starting +1 after the found id
        relation.offset(offset + 1).limit(count)
      end
    end
    Area.ordered_by_population.extending(Pager).records_after_id(id: 8, count: 3)
当返回一个
关系时
可以进行扩展,比如对接下来3条记录的总数求和

    Area.ordered_by_population
    .extending(Pager)
    .records_after_id(id: 8, count: 3)
    .sum(:population)

更多信息请参见id之后的
记录方法可以定义如下

    module Pager
      def records_after_id(id:, count:)
        relation = self.dup
        # perform the query and find the index of the id
        offset = relation.pluck(:id).find_index(id)
        # OFFSET LIMIT query starting +1 after the found id
        relation.offset(offset + 1).limit(count)
      end
    end
    Area.ordered_by_population.extending(Pager).records_after_id(id: 8, count: 3)
那么你可以这样称呼它

    module Pager
      def records_after_id(id:, count:)
        relation = self.dup
        # perform the query and find the index of the id
        offset = relation.pluck(:id).find_index(id)
        # OFFSET LIMIT query starting +1 after the found id
        relation.offset(offset + 1).limit(count)
      end
    end
    Area.ordered_by_population.extending(Pager).records_after_id(id: 8, count: 3)
当返回一个
关系时
可以进行扩展,比如对接下来3条记录的总数求和

    Area.ordered_by_population
    .extending(Pager)
    .records_after_id(id: 8, count: 3)
    .sum(:population)

有关更多信息,请访问

,感谢您提供有用的说明。不幸的是,我的用例与分页方法不兼容。问题是-表格在不断变化:正在添加行。因此,10秒前5页的内容可能与此页的当前内容不同。我的客户不是一个分页方法有效的网页。谢谢你的有用说明。不幸的是,我的用例与分页方法不兼容。问题是-表格在不断变化:正在添加行。因此,10秒前5页的内容可能与此页的当前内容不同。我的客户机不是一个分页方法有效的网页。