Hmm, to me 'last' logically operates on the return result of the query,
which I would expect to be a collection.  If you were to optimize this:

Task.all(:limit => 10, :order => [ :ordering.asc ]).last

It seems like behind the scenes it should be turned into something like one
of these:

Task.all(:order => [ :ordering.asc ])[9]
Task.first(:offset => 9, :order => [ :ordering.asc ])

Both of which optimize to:

SELECT "id", "title", "ordering" FROM "tasks" ORDER BY "ordering" LIMIT 10
OFFSET 9

I'll probably go with the '.first' one since it's clear where the query
ends, but just sayin'.  I think it can be done without sub queries.  I don't
really think the user should run into DM Query objects unless they're
looking for them.

Thanks for a great tool!

On Fri, Jan 14, 2011 at 2:36 PM, RipTheJacker <[email protected]> wrote:

> I don't really think it's a bug. Calling Thing.all.last does a query
> for the last item in the db, because Thing#all returns a DM Query, and
> the #last updates that query.
>
> Here are ways using mysql:
> http://www.mysqltutorial.org/select-nth-highest-record-database-table-using-mysql.aspx
>
> As you can see, they all rely on sub queries, some of which I don't
> think can be done in DM without writing sql.
>
> Here are other approaches:
> Thing.all(:limit =>10).to_a.last  <- will find 10 records and return
> the last of the array
> Thing.all(:limit => 10) - Thing.all(:limit => 9)  <- executes a single
> query returning an array of the 1 item.
>
> I really think the offset approach you already figured out is the best
> though.
>
>
> On Jan 13, 9:45 pm, Robert Fletcher <[email protected]> wrote:
> > Well, I discovered this workaround:
> >
> > a = Task.all(:order => [ :ordering.asc ])[9]
> >
> > Looks like this optimizes to what the previous one probably ought to.  It
> > uses OFFSET.
> >
> >
> >
> > On Thu, Jan 13, 2011 at 7:33 PM, lobati <[email protected]> wrote:
> > > So I'm trying to get the nth result from the database:
> >
> > > a = Task.all(:limit => 10, :order => [ :ordering.asc ]).last
> >
> > > but this query, instead of returning the 10th item actually returns
> > > the last item in the database.  I get the same results if I do this:
> >
> > > a = Task.all(:limit => 10, :order => [ :ordering.asc ])
> > > a = a.last
> >
> > > However, I get the results I want if I do something like this:
> >
> > > a = Task.all(:limit => 10, :order => [ :ordering.asc ])
> > > a.each do |task|
> > >  # do nothing
> > > end
> > > a = a.last
> >
> > > I gather this is the result of some query optimization going on, but
> > > this is a bug, right?  So for the time being, is there are better way
> > > of forcing the query to take place before '.last' and/or is there a
> > > more efficient way for me to get the 10th record with the above
> > > condition?
> >
> > > --
> > > You received this message because you are subscribed to the Google
> Groups
> > > "DataMapper" group.
> > > To post to this group, send email to [email protected].
> > > To unsubscribe from this group, send email to
> > > [email protected]<datamapper%[email protected]>
> <datamapper%2Bunsubscribe@googlegrou ps.com>
> > > .
> > > For more options, visit this group at
> > >http://groups.google.com/group/datamapper?hl=en.
>
> --
> You received this message because you are subscribed to the Google Groups
> "DataMapper" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected]<datamapper%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/datamapper?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"DataMapper" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/datamapper?hl=en.

Reply via email to