views:

40

answers:

2

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?

+1  A: 

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 }
jigfox
There will be a lot of data, so the second approach isn't really viable. The first *might* be ok, and was something I'd thought of, but actually what I might try and do is have an auto-populated rowcount column on this model and use the MOD approach on that.
colinramsay
+1  A: 

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.

nathanvda
I'm using MySQL here unfortunately.
colinramsay
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")` might work?
nathanvda
Yes, I think this is the best approach so far. It's made a bit more complicated in my scenario as I was using finders which were scoped to the parent record, but with a bit of rewriting your suggestion fits in nicely. Thanks!Do you want to add it as a separate answer which I will then accept?
colinramsay