Recordset Iterating - mysql

I want to iterate through records returned from a MySQL database using Perl, but only ten records at a time. The reason is that the server component can only handle 10 items per request.
For example:
If the query returned 35 records then
I have to send the data in 4 requests:
Request # # of Records
-------- --------
1 10
2 10
3 10
4 5
What is the best way to accomplish the task?

Look at the LIMIT clause for MySQL. You could have a query like:
SELECT * from some_table LIMIT 0, 10;
SELECT * from some_table LIMIT 10, 10;
etc. where the first number after LIMIT is the offset, and the second number is the number of records.
You'd of course first need to do a query for the total count and figure out how many times you'll need to run your select query to get all results.
Alternatively, in Perl you can use an ORM package like DBIx::Class that can handle pagination through sets of results and auto-retrieving them for you.

You can adjust the query to select 10 rows:
select *
from yourtable
order by idcolumn
limit 10;
When iterating over the rows, store the ID of the row you process. After you've processed 10 rows, fetch the next 10:
select *
from yourtable
where idcolumn > stored_id
order by idcolumn
limit 10;
Continue the last query until it returns less than 10 rows.

For first page:
SELECT *
FROM table1
ORDER BY
field
LIMIT 0, 10
For seconds page:
SELECT *
FROM table1
ORDER BY
field
LIMIT 10, 10
etc.

Related

Query Limit from MYSQL

I have database with about 500K row in it. I want get random row from row like 1 to 5000 and its limit result limit need like 100.
My current query is like below
'SELECT * FROM user where status='0' LIMIT 10,100'
what should I change or use for get limited random row, so I can get fast result without memory consume ?
Thanks
A database table is an unordered set, so you'll have to provide some order to get 1 to 5000 rows (otherwise those will be any 1 to 5000 rows), may be based on userid.
Once you have that, you can limit the rows in subquery and sort by rand() and get first 100 like this:
select *
from (select
*
from user
where status = 0
order by /* set of columns, may be user_id*/
limit 1, 5000
) t order by rand() limit 100;
This query gives you any 100 random rows from your 5000k rows
select * from user where status='0' order by rand() limit 100

How to get next set of data on select top

I loaded the result set with top 10 rows as follows.
SELECT * FROM Persons LIMIT 10;
Now how to select next 10 rows.? Like what in google search results can be toggled between search results.
Pardon if question sounds silly because i didn't found any relevant answer on google.
You can give the LIMIT clause a starting point, like this:
SELECT * FROM Persons LIMIT 50, 10;
This would mean the offset is 50 (it skips the first 50 rows), and the next 10 rows are selected. See also in the manual: MySQL SELECT Syntax.
Use OFFSET + LIMIT to do this
SELECT * FROM Persons
ORDER BY somecol
OFFSET 10 LIMIT 10 -- LIMIT 10 OFFSET 10
For Mysql
SELECT * FROM Persons
ORDER BY somecol
LIMIT 10 OFFSET 10 --LIMIT 10,10
Note: Make sure you add Order by to get meaningful results

MySQL database resultset with values as close to a number "x" as possible

Im trying to get a result set that contains the 10 values that are closest to, in this case, the number 3.
I have a database that has values in a column named rated which can be 1,2,3,4 or 5. What im trying to do is query the database and return the first 10 rows that have the values closest to 3. The values can be above 3 or below 3. I should note that these values in the rated column are floats.
I then need to sort these rows in order so that rows with value of 3 are first and then the row with lowest offset (+/-) from 3.
Is there any SQL query that can return atleast the result set of values closest to 3 ? or am i going to have to return the whole db and sort it myself?
To get the first 10 rows with highest value down i used the statement
SELECT * FROM tabs ORDER BY 5 DESC LIMIT 10";
5 refers to the column rated
Is there some way to modify this to do what i want ?
Thanks
If I understand your problem correctly, this should do the trick:
select *
from tabs
order by abs(`rated` - 3) asc
limit 10
Note that it sorts by the difference in ascending order, so those with a difference of 0 will come first.
SELECT * FROM tabs ORDER BY ABS(3 - Rate) ASC LIMIT 10
If I got right what you need try:
select *
from (
select
case when -(3-rated) > 0 then -(3-rated) else (3-rated) end as distance,
tabs.*
from tabs
) subsel
order by distance
limit 10

MySQL: LIMIT by a percentage of the amount of records?

Let's say I have a list of values, like this:
id value
----------
A 53
B 23
C 12
D 72
E 21
F 16
..
I need the top 10 percent of this list - I tried:
SELECT id, value
FROM list
ORDER BY value DESC
LIMIT COUNT(*) / 10
But this doesn't work. The problem is that I don't know the amount of records before I do the query. Any idea's?
Best answer I found:
SELECT*
FROM (
SELECT list.*, #counter := #counter +1 AS counter
FROM (select #counter:=0) AS initvar, list
ORDER BY value DESC
) AS X
where counter <= (10/100 * #counter);
ORDER BY value DESC
Change the 10 to get a different percentage.
In case you are doing this for an out of order, or random situation - I've started using the following style:
SELECT id, value FROM list HAVING RAND() > 0.9
If you need it to be random but controllable you can use a seed (example with PHP):
SELECT id, value FROM list HAVING RAND($seed) > 0.9
Lastly - if this is a sort of thing that you need full control over you can actually add a column that holds a random value whenever a row is inserted, and then query using that
SELECT id, value FROM list HAVING `rand_column` BETWEEN 0.8 AND 0.9
Since this does not require sorting, or ORDER BY - it is O(n) rather than O(n lg n)
You can also try with that:
SET #amount =(SELECT COUNT(*) FROM page) /10;
PREPARE STMT FROM 'SELECT * FROM page LIMIT ?';
EXECUTE STMT USING #amount;
This is MySQL bug described in here: http://bugs.mysql.com/bug.php?id=19795
Hope it'll help.
I realize this is VERY old, but it still pops up as the top result when you google SQL limit by percent so I'll try to save you some time. This is pretty simple to do these days. The following would give the OP the results they need:
SELECT TOP 10 PERCENT
id,
value
FROM list
ORDER BY value DESC
To get a quick and dirty random 10 percent of your table, the following would suffice:
SELECT TOP 10 PERCENT
id,
value
FROM list
ORDER BY NEWID()
I have an alternative which hasn't been mentionned in the other answers: if you access from any language where you have full access to the MySQL API (i.e. not the MySQL CLI), you can launch the query, ask how many rows there will be and then break the loop if it is time.
E.g. in Python:
...
maxnum = cursor.execute(query)
for num, row in enumerate(query)
if num > .1 * maxnum: # Here I break the loop if I got 10% of the rows.
break
do_stuff...
This works only with mysql_store_result(), not with mysql_use_result(), as the latter requires that you always accept all needed rows.
OTOH, the traffic for my solution might be too high - all rows have to be transferred.

Random row from big query result

I need to get 1-2 rows from query result retrived with SQL select on indexed columns without getting the whole record set.
For example I will retrieve 10 000 records using query
SELECT * FROM table WHERE field 1>1 AND field1 < 10
but I need only 1 random row from this query regarding to highload of my database.
I can use
SELECT * FROM table WHERE field 1>1 AND field1 < 10 LIMIT 100, 1
But I don't know records numebr to use correct offset range
How can I achieve this goal?
You could use ORDER BY RAND()
SELECT * FROM table WHERE field1 > 1 AND field1 < 10 ORDER BY RAND() LIMIT 1
This will return 1 random row with field1 in between 1 and 10
How about restricting the records you select in the first place?
SELECT * FROM table WHERE field1 IN (CONVERT(RAND()*10,SIGNED),CONVERT(RAND()*10,SIGNED)) LIMIT 2