This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
MySQL select 10 random rows from 600K rows fast
I need to pull from a table a random id. At this moment only a few records exists but with time they will grow. What methods of getting this id are in Php or MySql, and what are the trade offs, consequences between them. One last thing i need speed and performance.
select * from YOUR_TABLE order by rand() limit 1
You can achieve this direct in your SQL:
SELECT `idfield` FROM `table` ORDER BY RAND() LIMIT 0,1;
Also see here for some alternatives.
This will be a simple means of execution than building the randomisation in your PHP and then passing to mySQL, though the link above details the merits of the various approaches.
SELECT id FROM table ORDER BY RAND() LIMIT 1
What this does is basically: take the table, order the records by a random number, and get the first record's ID.
There is already a lot of questions and answer about that:
Random Records Mysql PHP
mysql query with random and desc
If you have less that 500,000 records, the RAND() is perfectly fine.
SELECT * FROM tbl_name ORDER BY RAND() LIMIT 1
Well you can obtain a random number with RAND(), but you would still have to call that method/function until you actually get something (you can have 1,2,5,6,100 as id`s due to deletion).
there is a post on this http://jan.kneschke.de/projects/mysql/order-by-rand/
Procedures can be usefull (but said to be slow...):
1 var to get the maximum value
then produce a random within 1 and that interval (or get the minimum)
then query
Related
I would like to construct a query that displays all the results in a table, but is offset by 5 from the start of the table. As far as I can tell, MySQL's LIMIT requires a limit as well as an offset. Is there any way to do this?
From the MySQL Manual on LIMIT:
To retrieve all rows from a certain
offset up to the end of the result
set, you can use some large number for
the second parameter. This statement
retrieves all rows from the 96th row
to the last:
SELECT * FROM tbl LIMIT 95, 18446744073709551615;
As you mentioned it LIMIT is required, so you need to use the biggest limit possible, which is 18446744073709551615 (maximum of unsigned BIGINT)
SELECT * FROM somewhere LIMIT 18446744073709551610 OFFSET 5
As noted in other answers, MySQL suggests using 18446744073709551615 as the number of records in the limit, but consider this: What would you do if you got 18,446,744,073,709,551,615 records back? In fact, what would you do if you got 1,000,000,000 records?
Maybe you do want more than one billion records, but my point is that there is some limit on the number you want, and it is less than 18 quintillion. For the sake of stability, optimization, and possibly usability, I would suggest putting some meaningful limit on the query. This would also reduce confusion for anyone who has never seen that magical looking number, and have the added benefit of communicating at least how many records you are willing to handle at once.
If you really must get all 18 quintillion records from your database, maybe what you really want is to grab them in increments of 100 million and loop 184 billion times.
Another approach would be to select an autoimcremented column and then filter it using HAVING.
SET #a := 0;
select #a:=#a + 1 AS counter, table.* FROM table
HAVING counter > 4
But I would probably stick with the high limit approach.
As others mentioned, from the MySQL manual. In order to achieve that, you can use the maximum value of an unsigned big int, that is this awful number (18446744073709551615). But to make it a little bit less messy you can the tilde "~" bitwise operator.
LIMIT 95, ~0
it works as a bitwise negation. The result of "~0" is 18446744073709551615.
You can use a MySQL statement with LIMIT:
START TRANSACTION;
SET #my_offset = 5;
SET #rows = (SELECT COUNT(*) FROM my_table);
PREPARE statement FROM 'SELECT * FROM my_table LIMIT ? OFFSET ?';
EXECUTE statement USING #rows, #my_offset;
COMMIT;
Tested in MySQL 5.5.44. Thus, we can avoid the insertion of the number 18446744073709551615.
note: the transaction makes sure that the variable #rows is in agreement to the table considered in the execution of statement.
I ran into a very similar issue when practicing LC#1321, in which I have to select all the dates but the first 6 dates are skipped.
I achieved this in MySQL with the help of ROW_NUMBER() window function and subquery. For example, the following query returns all the results with the first five rows skipped:
SELECT
fieldname1,
fieldname2
FROM(
SELECT
*,
ROW_NUMBER() OVER() row_num
FROM
mytable
) tmp
WHERE
row_num > 5;
You may need to add some more logics in the subquery, especially in OVER() to fit your need. In addition, RANK()/DENSE_RANK() window functions may be used instead of ROW_NUMBER() depending on your real offset logic.
Reference:
MySQL 8.0 Reference Manual - ROW_NUMBER()
Just today I was reading about the best way to get huge amounts of data (more than a million rows) from a mysql table. One way is, as suggested, using LIMIT x,y where x is the offset and y the last row you want returned. However, as I found out, it isn't the most efficient way to do so. If you have an autoincrement column, you can as easily use a SELECT statement with a WHERE clause saying from which record you'd like to start.
For example,
SELECT * FROM table_name WHERE id > x;
It seems that mysql gets all results when you use LIMIT and then only shows you the records that fit in the offset: not the best for performance.
Source: Answer to this question MySQL Forums. Just take note, the question is about 6 years old.
I know that this is old but I didnt see a similar response so this is the solution I would use.
First, I would execute a count query on the table to see how many records exist. This query is fast and normally the execution time is negligible. Something like:
SELECT COUNT(*) FROM table_name;
Then I would build my query using the result I got from count as my limit (since that is the maximum number of rows the table could possibly return). Something like:
SELECT * FROM table_name LIMIT count_result OFFSET desired_offset;
Or possibly something like:
SELECT * FROM table_name LIMIT desired_offset, count_result;
Of course, if necessary, you could subtract desired_offset from count_result to get an actual, accurate value to supply as the limit. Passing the "18446744073709551610" value just doesnt make sense if I can actually determine an appropriate limit to provide.
WHERE .... AND id > <YOUROFFSET>
id can be any autoincremented or unique numerical column you have...
I would like to know if it is possible to retrive one single random row from search results. I mean I have query like this:
SELECT mp.name,mp.icon,mp.id,mp.wspx,mp.wspy,ms.icon FROM maps_points as mp JOIN maps_section as ms ON(ms.id = mp.section)
I would like to get one random row from results generated from this query. Is that possible with one mysql query or should I just get all results and get this one random in PHP?
a simple way is to add ORDER BY RAND() LIMIT 1 to the query. Do take a look at some of the reasons why this can be a bad idea though, e.g.
Why don't use mysql ORDER BY RAND()?
MySQL: Alternatives to ORDER BY RAND()
How can i optimize MySQL's ORDER BY RAND() function?
SELECT mp.name,mp.icon,mp.id,mp.wspx,mp.wspy,ms.icon
FROM maps_points as mp
JOIN maps_section as ms ON(ms.id = mp.section)
ORDER BY RAND() LIMIT 1
Ok, I knew this one, but is there better and faster way to do that ? I mean I've seen some other approaches but they were all about random row from table and I need to pick random row from some set of results :)
i was using order by rand() to generate random rows from database without any issue but i reaalised that as the database size increase this rand() causes heavy load on server so i was looking for an alternative and i tried by generating one random number using php rand() function and put that as id in mysql query and it was very very fast since mysql was knowing the row id
but the issue is in my table all numbers are not availbale.for example 1,2,5,9,12 like that.
if php rand() generate number 3,4 etc the query will be blank as there is no id with number 3 , 4 etc.
what is the best way to generate random numbers preferable from php but it should generate the available no in that table so it must check that table.please advise.
$id23=rand(1,100000000);
SELECT items FROM tablea where status='0' and id='$id23' LIMIT 1
the above query is fast but generate sometimes no which is not availabel in database.
SELECT items FROM tablea where status=0 order by rand() LIMIT 1
the above query is too slow and causes heavy load on server
First of, all generate a random value from 1 to MAX(id), not 100000000.
Then there are at least a couple of good solutions:
Use > not =
SELECT items FROM tablea where status='0' and id>'$id23' LIMIT 1
Create an index on (status,id,items) to make this an index-only query.
Use =, but just try again with a different random value if you don't find a hit. Sometimes it will take several tries, but often it will take only one try. The = should be faster since it can use the primary key. And if it's faster and gets it in one try 90% of the time, that could make up for the other 10% of the time when it takes more than one try. Depends on how many gaps you have in your id values.
Use your DB to find the max value from the table, generate a random number less than or equal to that value, grab the first row in which the id is greater than or equal to your random number. No PHP necessary.
SELECT items
FROM tablea
WHERE status = '0' and
id >= FLOOR(1 + RAND() * (SELECT MAX(id) FROM tablea))
LIMIT 1
You are correct, ORDER BY RAND() is not good solution if you are dealing with large datasets. Depending how often it needs to be randomized, what you can do is generate a column with a random number and then update that number at some predefined interval.
You would take that column and use it as your sort index. This works well for a heavy read environment and produces predicable random order for a certain period of time.
A possible solution is to use limit:
$id23=rand(1,$numberOfRows);
SELECT items FROM tablea where status='0' LIMIT $id23 1
This wont produce any missed rows (but as hek2mgl mentioned) requires knowing the number of rows in the select.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Selecting Random Rows in MySQL
I'm creating a simple web application using PHP and MySQL. In it, I need to randomly select a small set of rows from a table in a random order. How can I achieve such thing using MySQL?
SELECT * FROM table ORDER BY RAND() LIMIT 10;
Edit:
Useful information about the MySQL RAND() function can be found here.
select * from table order by rand() limit 10
Note that order by rand() with large dataset is very slow but in your case it's not a problem.
you could do that using RAND() function .
SELECT questine FROM tablename ORDER BY RAND() LIMIT 10
will select 10 questines at random under assumption the questine is stored under field questine
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How to request a random row in SQL?
I have table:
name,age,school
jane,15,zu
peter,16,zu
john,15,stu
Tomas,15,kul
viera,17,stu
tibor15,zu
I want select from this table 1 person (randomly) per school
select * from table group by school order by rand()
It's terribly innefficient since it's ORDERing the entire table randomly, and then GROUPing on a potentially huge unindexed temporary table, but this works.
SELECT *
FROM (
SELECT *
FROM my_table
ORDER BY RAND()
)a
GROUP BY school
It would likely be more wise to break it down.
One query to retrieve a list of
schools.
For each school, one query to get a random student for that school.
See this post for some slick tricks on how to get single random values efficiently.
If you are using php (as the tag suggests), run SELECT * FROM table; then generate a random number based on the number of results in the query. For example:
i = floor(random()*query.length);
Then seek to the record indicated seek(i) and viola, you have a random entry =)
You'll have to use your own knowledge/documentation for the exact syntax, I haven't touched PHP in a while, but the logic is sound.
Gary