【问题标题】:ActiveRecord Find - Skipping Records or Getting Every Nth RecordActiveRecord 查找 - 跳过记录或获取每 N 条记录
【发布时间】:2010-06-30 08:20:42
【问题描述】:

我想做一个查询,在其中选择一堆数据,但我希望能够通过只选择每三条记录,或者甚至每百分之一的记录来降低该数据的分辨率录音之类的。

有没有什么直接的方法可以用 ActiveRecord 做到这一点?

【问题讨论】:

    标签: sql ruby-on-rails activerecord


    【解决方案1】:

    如果您的模型有一个像id 这样的升序行且没有丢失任何数字,您可以执行以下操作:

    Model.all(:condition => "models.id%3=0")
    

    如果没有,您可以先从数据库中获取所有行,然后您可以这样做:

    models = Model.all
    third_models = models.reject{ |model| models.index(model) % 3 != 0 }
    

    【讨论】:

    • 会有很多数据,所以第二种方法并不可行。第一个可能没问题,是我想到的,但实际上我可能会尝试在此模型上设置一个自动填充的行数列,并在其上使用 MOD 方法。
    【解决方案2】:

    在 Oracle 中我会这样写:

    YourModel.find(:conditions => 'MOD(ROWNUM,3) = 0') 
    

    这样做的好处是过滤器发生在数据库中,因此不会检索到所有内容。

    在 PostgreSQL 中,这称为ROW_NUMBER(实际上这是 SQL 标准)。在 MySQL 中这是不支持的。

    在 mysql 中,您可以使用 SELECT @rownum:=@rownum+1 rownum, t.* FROM (SELECT @rownum:=0) r, mytable t; 模拟 rownum。所以我猜像

    Bar.find_by_sql("select * from (SELECT @rownum:=@rownum+1 rownum, t.* FROM (SELECT @rownum:=0) r, mytable t) where mod(rownum,3) = 0") 
    

    应该可以。

    【讨论】:

    • 不幸的是,我在这里使用 MySQL。
    • 在 mysql 中,您可以使用 SELECT @rownum:=@rownum+1 rownum, t.* FROM (SELECT @rownum:=0) r, mytable t; 模拟 rownum。所以我想像Bar.find_by_sql("select * from (SELECT @rownum:=@rownum+1 rownum, t.* FROM (SELECT @rownum:=0) r, mytable t) where mod(rownum,3) = 0") 这样的东西可能有用吗?
    • 是的,我认为这是迄今为止最好的方法。在我的场景中它变得有点复杂,因为我使用的是范围为父记录的查找器,但是稍微重写你的建议很适合。谢谢!是否要将其添加为单独的答案,然后我会接受?
    猜你喜欢
    • 1970-01-01
    • 2010-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多