SQL limit number of groups - mysql

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?

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.

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)

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

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.

Related

get records from table starting from row 5 onwards

I have a mysql Database and I want to get the records starting from row 5 onwards. This is what i am sing right now
SELECT * FROM categories WHERE status = 1
limit 5 18446744073709551615 ORDER BY sortOrder ASC
But it is throwing me an error
Error Executing Database Query.
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '18446744073709551615
ORDER BY
sortOrder ' at line 6
Also i am not sure at this point if this is the correct way of doing it or not
Thanks
You require OFFSET
Example:
SELECT something FROM table LIMIT $limit OFFSET $offset;
//or alternatively
SELECT something FROM table LIMIT $offset,$limit;
Regarding your error:
Remove the number - what is it for in the first place?
Your statement should be:
SELECT * FROM categories WHERE status = 1
OFFSET 5 ORDER BY sortOrder ASC
You missed a comma , in your sql query.. just change it to the following:
SELECT * FROM categories WHERE status = 1
limit 5, 18446744073709551615 ORDER BY sortOrder ASC
↑
Explanation: LIMIT with two arguments (comma separated) will take first argument as OFFSET and second as the maximum number of rows to return.
Alternatively, if you just want to get all rows from a particular record.. you can use OFFSET keyword. The following will fetch rows starting from 5th row.
SELECT * FROM categories WHERE status = 1
OFFSET 5 ORDER BY sortOrder ASC
Perhaps You need to just Rearrange the sequence of Instruction.
Make Sure 'sortOrder' column exists in your Categories table.
The Following Query should work,
Select * from Categories Where status =1
ORDER BY sortOrder ASC
Limit 4, 999980090909
If you want to get the rows starting from 5 , then your Limit value should start from 4 and the second value can be some larger number.
Hope this helps you!

sql syntax error while using top query

I'm using the top query for my table but facing the error
You have an error in your sql syntax, chekck the manual that
corresponds to your mysql server version for the right sytntax to use
near '4 * from sitemain order by siteid desc limit 0,30' at line 1
here is the code which i used
SELECT top 4 *
FROM sitemain
ORDER BY siteid DESC
You are mixing MySQL and TSQL syntax together. The query obviously is MySQL (from the error message). What you want is
SELECT * FROM sitemain ORDER BY siteid DESC LIMIT 0,4
What you loking for is actually 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):
Documentation:
https://dev.mysql.com/doc/refman/5.0/en/select.html
SELECT *
FROM sitemain
ORDER BY siteid DESC
LIMIT 4
SELECT *
FROM sitemain
ORDER BY siteid DESC
LIMIT 4
With MySQL you need to use the LIMIT command as explained here:
Limit is used to limit your MySQL query results to those that fall within a specified range. You can use it to show the first X number of results, or to show a range from X - Y results. It is phrased as Limit X, Y and included at the end of your query. X is the starting point (remember the first record is 0) and Y is the duration (how many records to display).
SELECT *
FROM sitemain
ORDER BY siteid DESC
LIMIT 4

Convert MSSQL paging statement to MySQL paging statement

I wish to convert a basic paging MSSQL statement to MySQL.
particularly the ROW_NUMBER() and OVER combined with ORDER BY are tricky to me.
SELECT * FROM (select ROW_NUMBER() OVER (ORDER BY publishdate DESC) as RowNum,
* FROM news WHERE publishdate <=getdate()) as info
WHERE RowNum > 0 AND RowNum <= (100)
How would I convert thisto a MySQL statement?
Try LIMIT syntax like this:
select *
FROM news WHERE publishdate <= CURDATE()
LIMIT 0,100; # Retrieve rows 1-100
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):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15

Return only one tuple of SQL query result

I want to do a query like
select * from chr2;
but only have MySQL return the first tuple (or an arbitrary) tuple instead of all of them.
How do I do it?
Use the LIMIT clause:
SELECT * FROM chr2 LIMIT 1;
If you want an arbitrary row returned, you have to sort your rows by an random col like this (MySQL docu):
SELECT * FROM chr2
ORDER BY RAND()
LIMIT 1;
On large tables, however, you might run into performance problems with this, as there a random value has to be created for each row and the table has to be sorted according to this column.
Try this ::
select * from chr2 limit 1

rollup with limit?

I'm having trouble with one of my MySQL queries:
SELECT id,Portfolio,Agency,Program,Objective,billion1,value11_12,
Proportion1,billion,value12_13,Percentage,Difference,
Diff_Percent,PIT,TOS,Actual_PIT,Actual_TOS,SUM(billion),SUM(Percentage),
SUM(PIT),SUM(TOS),SUM(Actual_PIT),SUM(Actual_TOS)
FROM budget_table
GROUP BY 'sum(Billion)'
WITH ROLLUP
LIMIT 0,100
The query works but I can't get the limit to work with the rollup. You can see the results of the query at BudgetAus
It is totalling all results rather than the first 100 which is what I am now trying to achieve. I have also tried just using LIMIT 100 but can't get anything to work. I tried using EXPLAIN (for the first time) in MySQL on the database and it said that the query executed although I didn't see any results- but as I've never used it before I wasn't sure what to look for. I'm new to programming and use WAMP rather than a CLI.
I'm also not sure whether to start my limits from 0 or 1?
GROUP BY 'sum(Billion)'
This does not group by each distinct value of the Billion column. This groups by a single value, the constant string literal 'sum(Billion)'. So you'll get one group, because all rows have the same value when you use a constant string literal as your grouping expression.
Take the quotes off when you put an expression in the GROUP BY column.
Then you'll find that this is not a valid expression for grouping anyway.
SUM() operators can't be used in the GROUP BY expression, as SUM() is an aggregate operator, and hence makes no sense inside a GROUP BY
Therefore you should be using id, or some other field, for the GROUP BY.
The second parameter to LIMIT (the offset parameter) starts at 0, not 1.
My son (who is around here somewhere but I don't know his username) decided he wanted to solve this for me today and provided the following solution:
//Get the main result set
$result = mysql_query("SELECT * FROM budget_table ORDER BY Percentage DESC LIMIT 0,100 ");
//Build an array of the ids for the result set
$ids = array();
$rows = mysql_num_rows($result);
//Get id for each row and add to the ids
for($i = 0; $i < $rows; $i++) $ids[] = mysql_result($result, $i, "id");
//Join the ids into a string for use with IN()
$ids_str = implode(",", $ids);
//Get the sums for only the ids of the resultset above
$result2 = mysql_query("SELECT SUM(billion),SUM(Percentage),SUM(PIT),SUM(TOS),SUM(Actual_PIT),SUM(Actual_TOS) FROM budget_table WHERE id IN($ids_str)");