Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActiveRecord Find - Skipping Records or Getting Every Nth Record

I'd like to do a query where I select a bunch of data, but I'd like to be able to then decrease the resolution of that data by only selecting, say, every third record, or maybe even every hundredth record, or whatever.

Is there any straightforward way to do this with ActiveRecord?

like image 779
Colin Ramsay Avatar asked Jun 30 '10 08:06

Colin Ramsay


People also ask

What is recordnotfound in ActiveRecord?

If one or more records cannot be found for the requested ids, then ActiveRecord::RecordNotFound will be raised. If the primary key is an integer, find by id coerces its arguments by using to_i. NOTE: The returned records are in the same order as the ids you provide.

What is the use of find method in ActiveRecord?

The find method will raise an ActiveRecord::RecordNotFound exception if no matching record is found. You can also use this method to query for multiple objects. Call the find method and pass in an array of primary keys. The return will be an array containing all of the matching records for the supplied primary keys.

What is the active record query interface?

1 What is the Active Record Query Interface? If you're used to using raw SQL to find database records, then you will generally find that there are better ways to carry out the same operations in Rails. Active Record insulates you from the need to use SQL in most cases.

What is the difference between first and last methods in ActiveRecord?

The first! method behaves exactly like first, except that it will raise ActiveRecord::RecordNotFound if no matching record is found. The last method finds the last record ordered by primary key (default). For example: The SQL equivalent of the above is:


2 Answers

If your Model has an ascending row like id without missing any number you can do something like this:

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

If not you can first fetch all rows from the database and then you can do this:

models = Model.all
third_models = models.reject{ |model| models.index(model) % 3 != 0 }
like image 167
jigfox Avatar answered Oct 20 '22 14:10

jigfox


In Oracle i would write that as follows:

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

this has the advantage that the filter happens at the database, so not everything is retrieved.

In PostgreSQL this is called ROW_NUMBER (actually that is the SQL-standard). In MySQL this is not supported.

In mysql you can mimic rownum using SELECT @rownum:=@rownum+1 rownum, t.* FROM (SELECT @rownum:=0) r, mytable t;. So i guess something like

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

should work.

like image 38
nathanvda Avatar answered Oct 20 '22 12:10

nathanvda