How can I select a single random entry from a MySQL database using PHP?
I want to select the Author, AuthorText, and Date?
SELECT Author, AuthorText, Date FROM table ORDER BY RAND() LIMIT 1
Take a look to this interesting article:
“Do not use ORDER BY RAND()” or “How to get random rows from table?”
ORDER BY rand() LIMIT 1
will sort all the rows in the table, which can be extremely slow.
Better solution : say your table has the usual primary key auto-increment field, generate a rendom number between min(id) and max(id) and select the closest id.
It will not be as random as a "true" random selection, because a id after a large hole of deleted ids will have a higher probability of being chosen. But it will take 50 µs instead of 2 seconds if your table is large...
SET #t = (SELECT FLOOR(a + (b-a)*rand()) FROM (SELECT min(id) as a, max(id) as b FROM table)
SELECT * FROM table WHERE id>#t ORDER BY id LIMIT 1;
You can order by a random & restrict to 1 row as follows:
select
author, authortext, date
from bookstable
order by rand()
limit 1
Related
My table has around 10k rows. How can I query select 1 random row of the last 10 added rows? I have a date column that is datetime of when the row was added.
This is one I use to get the last 10 rows:
SELECT id FROM mytable order by date desc LIMIT 10
I know I can do SELECT id FROM mytable ORDER BY RAND() LIMIT 1 but that just choose any random row, not from the last 10 rows.
One method uses a subquery:
SELECT t.*
FROM (SELECT id
FROM mytable
ORDER BY date DESC
LIMIT 10
) t
ORDER BY rand()
LIMIT 1;
This version uses the syntax conventions for MySQL.
You can use select * in the subquery to fetch the whole row.
I'm working on php small project, here I need first 5 records from beginning of records and last record 1 from end of the table's record. I don't know how to write a single mysqli query.
Any help will be appreciated. Thanks in advance.
SQL tables represent unordered sets. So, there is no such thing as the first five rows or last row -- unless a column explicitly defines the ordering.
Often, a table has some sort of auto-incremented id column, which can be used for this purpose. If so, you can do:
(select t.*
from t
order by id asc
limit 5
) union all
(select t.*
from t
order by id desc
limit 1
);
Notes:
Sometimes, an insert date/time column is the appropriate column to use.
You want to use union all rather than union -- unless you want to incur the overhead of removing duplicate values.
For this formulation, if there are fewer than 6 rows, then you will get a duplicate.
The UNION operator allows this, carefully toying with the ORDER BY and LIMIT clauses :
(SELECT * FROM table ORDER BY field ASC LIMIT 5)
UNION
(SELECT * FROM table ORDER BY field DESC LIMIT 1)
I have a scenario, where I need to find a random winner from a group of entries.
The entries can be multiple times and now I am fetching all the records grouped by user ID and using PHP's array_rand() method to find a random winner. The grouping is used to avoid duplicate elements.
Here I am facing two problems
The query is timing out as it is dealing with almost 10000000 records.
PHP memory is exhausted because of large number of records.
My current query is a simple one and it looks like this
SELECT id, userID from table where id!= 1111 and created_at >='2017-08-10' group by userID
What is the best method, which will work on this large-scale?
Use ORDER BY RAND() and limit results to 1 to avoid memory getting exhausted.
SELECT id, userID
from table
where id!= 1111 and created_at >='2017-08-10'
group by userID
ORDER BY RAND()
LIMIT 1;
Try doing everything in SQL , might be faster.
SELECT id, userID
FROM table
WHERE id!= 1111 and created_at >='2017-08-10'
GROUP BY userID
ORDER BY RAND()
LIMIT 1;
May this will help
SELECT userID
FROM table AS t1 JOIN
(SELECT CEIL(RAND() *
(SELECT MAX(userID)
FROM table)) AS userID)
AS t2
where id!= 1111 and created_at >='2017-08-10'
ORDER BY t1.userID ASC
LIMIT 1
I want to select last 50 rows from MySQL database within column named id which is primary key. Goal is that the rows should be sorted by id in ASC order, that’s why this query isn’t working
SELECT
*
FROM
`table`
ORDER BY id DESC
LIMIT 50;
Also it’s remarkable that rows could be manipulated (deleted) and that’s why following query isn’t working either
SELECT
*
FROM
`table`
WHERE
id > ((SELECT
MAX(id)
FROM
chat) - 50)
ORDER BY id ASC;
Question: How is it possible to retrieve last N rows from MySQL database that can be manipulated and be in ASC order ?
You can do it with a sub-query:
SELECT * FROM
(
SELECT * FROM table ORDER BY id DESC LIMIT 50
) AS sub
ORDER BY id ASC;
This will select the last 50 rows from table, and then order them in ascending order.
SELECT * FROM table ORDER BY id DESC LIMIT 50
save resources make one query, there is no need to make nested queries
SELECT * FROM table ORDER BY id DESC, datechat DESC LIMIT 50
If you have a date field that is storing the date (and time) on which the chat was sent or any field that is filled with incrementally (order by DESC) or de-incrementally (order by ASC) data per row put it as second column on which the data should be ordered.
That's what worked for me!!!! Hope it will help!!!!
Use it to retrieve last n rows from mysql
Select * from tbl order by id desc limit 10;
use limit according to N value.
if anyone need this
you can change this into
SELECT
*
FROM
`table`
WHERE
id > ((SELECT
MAX(id)
FROM
chat) - 50)
ORDER BY id ASC;
into
SELECT
*
FROM
`table`
WHERE
id > (SELECT MAX(id)- 50 FROM chat)
ORDER BY id ASC;
select * from Table ORDER BY id LIMIT 30
Notes:
* id should be unique.
* You can control the numbers of rows returned by replacing the 30 in the query
I am creating an online store website that needs the functionality to select a random product from the database.
The idea is that there will be an advert for a random product that is different each time the webpage loads!
Using PHP, how would I go about doing this?
tbl_products
id
code
title
stock
cost
rrp
These are the rows I need to get access to from the database.
Thanks
A most straightforward solution would be this:
SELECT *
FROM tbl_products
ORDER BY
RAND()
LIMIT 1
However, this becomes less efficient as the number of products grows.
This solution:
Selecting random rows
is more efficient, though it still requires a full table scan.
If you product ids are distributes more or less uniformly, use this:
SELECT p.*
FROM (
SELECT
(
(
SELECT MAX(id)
FROM tbl_products
) -
(
SELECT MIN(id)
FROM tbl_products
)
) * RAND() AS rnd
) q
JOIN tbl_products p
ON id >= rnd
ORDER BY
id
LIMIT 1;
If you have gaps between ids, the products after large gaps will tend to be selected more often.
Instead of id, you may use a special unique column for this purpose which you should fill without gaps in a cron job.
ORDER BY RAND() is a well-known solution that has well-known problems.
If the product ids are a consecutive range of integers and there is a non-trivial number of rows, then it will much better to SELECT MAX(id) FROM products, generate a number of random integers between 1 and the result in PHP, and do SELECT * FROM products WHERE id IN (x, y, z) as a second query. If the ids are almost, but not quite, consecutive, you can adapt this solution to generate more random ids than needed to account for the fact that not all of them might be valid (the more fragmentation there is among ids, the more surplus numbers you should generate).
If the above is not an option, then querying like this will still be better than a pure ORDER BY RAND().
Here's a PHP solution
$range_res = mysql_query( " SELECT MAX(id) AS max_id , MIN(id) AS min_id FROM products ");
$range_row = mysql_fetch_object( $range_res );
$random = mt_rand( $range_row->min_id , $range_row->max_id );
$res = mysql_query( " SELECT * FROM products WHERE id >= $random LIMIT 0,1 ");