Reputation: 28147
I am trying to create a simple pagination but it seems to fail to limit
the number of results.
SELECT * FROM visits GROUP by clientID ORDER BY 'date' LIMIT $from, $to
I want to get only the first visit (chronologically) of every client and paginate the results.
If I make this query with $from = 6, $to = 12 it returns like 8 rows instead of 7.
What I'm doing wrong?
Upvotes: 5
Views: 2072
Reputation: 1269873
Your query does not return the first visit by date. To do this, you need to actually join in this information:
select v.*
from visits v join
(select clientid, MIN(date) as mindate
from visits
group by clientid
) vd
on v.clientid = vd.clientid and v.date = vd.date
order by clientid
limit $from - 1, $to - $from
Your originally query is returning an arbitrary set of columns about a given client. These columns are not even guaranteed to be from the same record. This is because you are using a MySQL (mis)feature, where you can have columns in the select
clause that are not in the group by
clause and are not the arguments to an aggregation function.
Upvotes: 1
Reputation: 80639
From MySQL's docs on LIMIT
clause
The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants (except when using prepared statements).
With two arguments, the first argument specifies the offset of the first row to return, and the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1).
When you chose $from
as 6 and $to
as 12; you are not selecting from 6 to 12; you will be selecting 12 rows, starting from $from + 1
= 7.
Upvotes: 6
Reputation: 25489
With the dbms and syntax you're using, the second number in the limit expression is the number of results allowed, not offset endpoints. So you're starting at 6 and allowing the next 12 results, not getting results 6-12.
If you want to get results 6-12, use limit 5,7
Upvotes: 2
Reputation: 6226
The first argument to the LIMIT cluase is the starting offset and the second is the number of rows to return. Therefore your query should be:
... LIMIT $from, ($to - $from)
Upvotes: 2