This question already has answers here:
MySQL: Alternatives to ORDER BY RAND()
(9 answers)
How to request a random row in SQL?
(30 answers)
Closed 6 years ago.
I have a table with about 70 columns and 120,000 rows of data. What I want to do is randomize a record and then displaying the values of others columns of this record.
If I do fetch all data,
$result=mysqli_query($link, 'SELECT id, column1, column2, column3, ..., column 70 from table');
while ($row=mysqli_fetch_array($result))
{
$info[] = array('id'=>$row['id'], 'column1'=>$row['column1'], ...);
}
$randindex = rand(0,count($info));
$id = $info[$randindex]['id'];
echo $info[$randindex]['column1']; echo $info[$randindex]['column2']; ....
I'm afraid that this will significantly slow down the process. So I want to query only the ID before randomization, and then use the randomized ID to retrieve the other values of that record in the database.
$result=mysqli_query($link, 'SELECT id from table');
while ($row=mysqli_fetch_array($result))
{
$info[] = $row['id'];
}
$randindex = rand(0,count($info));
$id = $info[$randindex];
and then retrieve all other fields of this particular record somehow. I asked how to do this in SQL here but I would like to know if there is any more efficient way by other means besides SQL. Do I need to do a loop like this?
In your code, do the following:
select min(id) as minid, max(id) as maxid
from table;
Then use php to generate a random id and do:
select t.*
from table t
where t.id >= $randid
order by id
limit 1;
With an index on id -- and reasonable assumptions about there not being too large gaps in the values -- then this will work well.
You can do the same thing in just one query:
select t.*
from table t cross join
(select min(id) as minid, max(id) as maxid from table) tt
where t.id >= minid + rand() * (tt.maxid - tt.minid)
order by id
limit 1;
you can use ORDER BY RAND() directly in the sql query:
SELECT * FROM table ORDER BY RAND() LIMIT 1
ORDER BY RAND() actually makes random order of you rows, and then you just do LIMIT 1 in order to get only one row, the first one.
I do not think it is valid. I think it's faster execute just one query with ORDER BY RAND ()
Related
I'm trying to have my query count the rows and have it return the most common name in that list, then from that it counts how many times that name appears and outputs the name and the amount of times its there
This is the code I'm using:
$vvsql = "SELECT * FROM votes WHERE sid=? ORDER BY COUNT(*) DESC LIMIT 1";
$vvresult = $db->prepare($vvsql);
$vvresult->execute(array($_GET['id']));
$vvcount = $vvresult->rowCount();
foreach ($vvresult->fetchAll(PDO::FETCH_ASSOC) as $row) {
echo $row['username'];
echo $vvcount;
}
However, it just displays the first username in the table and counts up the entire table. I'm pretty new to this so I'm sorry if this is a bad post or if it didn't make much sense.
You would seem to want:
SELECT name, COUNT(*) as cnt
FROM votes
GROUP BY name
ORDER BY COUNT(*) DESC
LIMIT 1;
Note the GROUP BY. You may also want to filter by sid but your question makes no mention of that.
select username, count(*) as c
FROM votes
GROUP BY username
ORDER BY c DESC
I want the database to show all the rows, except for the first and last ones, since I have CSS code for them.
I tried this:
SELECT * FROM db
WHERE
keywords LIKE '%example%' LIMIT 9999 OFFSET 1
AND
keywords LIKE '%example%' DESC LIMIT 9999 OFFSET 1
Since the row number may increase I can't write an exact number.
There really is no reason to complicate your query by trying to snip off these values at the SQL level, you could do:
$results = $db->query( /* regular query with all results */ );
array_pop($results);
array_shift($results);
// Now use $results, which now contains only the "middle" content
If you really want it at the DB level, you can use:
SELECT * FROM db
WHERE keywords LIKE '%example%'
AND id <> (SELECT MAX(ID) FROM TABLE)
AND id <> (SELECT MIN(ID) FROM TABLE)
You can use UNION like as
SELECT * FROM db WHERE keywords LIKE '%example%' order by keywords ASC limit 1 UNION SELECT * FROM db WHERE keywords LIKE '%example%' order by keywords DESC limit 1;
You can try this for instance:
SELECT * FROM TABLE WHERE ID != (SELECT MAX(ID) FROM TABLE) LIMIT 1,9844674507370
But like I said in the comment : It is strongly advisable that you handle this with PHP code, to avoid making 2 or more requests
You can do it without using LIMIT AND OFFSET
SELECT * FROM table_name WHERE id != (SELECT MAX(id) FROM table_name) AND id != (SELECT MIN(id) FROM table_name)
SELECT * FROM db
WHERE
keywords LIKE '%example%'
AND
id != (SELECT MAX(id) FROM db)
AND
id != (SELECT MIN(id) FROM db)
here id will be your auto increment key
1st : Simple you can handle this thing in php like below . avoid two query
$last_record =count($records)-1;
$i=0;
foreach($records as $key=>$row)
{
if($i==0){
//apply the css
}
if($i== $last_record ){
//apply the css
}
}
query :
SELECT * FROM db WHERE keywords LIKE '%example%'
Is possible, and how to ask MySQL for
SELECT * FROM my_table ORDER by row_id DESC LIMIT 8
get the last 8, newest record from my table, with randomized order for PHP showing method
$results = $mysqli->query($query);
while($row = $results->fetch_assoc()) {
echo $row['my_col_name'];
}
Colud I, and where put the rand() in my SQL query?
Without randomize I get last 8 rows ORDERED 10,9,8,7,6,5,4,3
I want to get in the following order:
9,7,5,4,6,10,3,8;
8,7,3,6,10,9,5,4
...
You can place it inside another select:
SELECT * FROM (SELECT * FROM my_table ORDER by row_id DESC LIMIT 8) t ORDER BY RAND()
Use a subquery:
SELECT t.*
FROM (SELECT t.*
FROM my_table t
ORDER by row_id DESC
LIMIT 8
) t
ORDER BY rand();
I am looking for a better way of doing this:
SELECT * FROM $tbl_name WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM $tbl_name ) ORDER BY id LIMIT 1;
It is slow and isn't very random, I get the same result every 10 or so query's.
This selects a random row from the table regardless of its ID.
So far I have this:
// Get amount of rows in database
$result = mysql_query("SELECT * FROM $tbl_name");
$num_rows = mysql_num_rows($result);
// Generate random number
$random_row = rand(1, $num_rows);
But I don't know how to get a certain row.
I do not mean
SELECT * FROM $tbl_name WHERE id = $random_row
Because my database has gaps in the ID column so it would sometimes fail.
Has anyone got script that can get a random result from a MySQL database without replying on IDs and is super fast? (the database contains about 20000 rows)
SELECT * FROM $tbl_name WHERE 1 ORDER BY RAND() LIMIT 1;
20,000 rows isn't really that much, the above should be fast enough.
Juhana is right by the book: "ORDER BY RAND() LIMIT 1", and of course 20k isn1t that much.
Other option will be with subselects:
SELECT [fields]
FROM myTable,
(SELECT FLOOR(MAX(myTable.id) * RAND()) AS randId FROM myTable) AS someRandId
WHERE myTable.id = someRandId.randId
discussed here
(please avoid select * when it`s unnecessary)
After some searching though the comments on the link Adi sent, I have found a decent solution.
SELECT * FROM $tbl_name T JOIN (SELECT CEIL(MAX(ID)*RAND()) AS ID FROM $tbl_name) AS x ON T.ID >= x.ID LIMIT 1;
Source: wanderr.com/jay/order-by-slow/2008/01/30
Seems to be very fast and very random!
I am coding a blog post kind of thing, where the author will post the article and it will be displayed in the front end, my problem starts for selecting the posts as i have to meet certain conditions for posting the news in the front end,
I have 4 fields in the database namely
title
pic_title
pic_brief
pic_detail
you guessed it right apart from the title table the rest of three will hold the path to the images in varchar datatype, which will be used to display as the post, the format of the front end is such that
a) there will be total of eight post
displaying in the front end (eight
entries from the database)
b) there will be three post on the top which will include the value from
the table title, pic_title and
pic_brief (total of 3 values)
c) and the rest five will contain just the title and pic_title
(excluding the three entries of top)
Please NOTE: i want the second query to exclude the top 3 record
which already exist in the top i.e
(first query = 3 post in descending
order, second query = 8 - first 3 = 5
post)
The Order of the Post i want is by id DESC
EDIT: I took the first query as
SELECT * FROM news ORDER BY id DESC LIMIT 3
Now if i take the same second query and try populating the values by desc order again the same records will be accessed
In simple words i want a query that will skip the last three records order by id DESC
How do i achieve this feat in PHP?
If you just want the SQL, here it is:
First query
SELECT * FROM `table` LIMIT 3
Second query
SELECT * FROM `table` LIMIT 3,5
(where table is the name of your table of course. Of course you may want to add some ORDER BY clause. To execute these queries in PHP, I suggest reading the manual. If you have any specific problems after doing so, then you can post a new question.
This is a situation where I'd likely opt to select all eight records at once - the less trips to the database, the better.
SELECT t.title,
t.pic_title,
t.pic_brief
FROM TABLE t
ORDER BY t.id DESC
LIMIT 8
...because the rest is just presentation:
$query = sprintf("SELECT t.title,
t.pic_title,
t.pic_brief
FROM TABLE t
ORDER BY t.id DESC
LIMIT 8");
// Perform Query
$result = mysql_query($query) or die( mysql_error() );
$rowcount = 1;
// Use result
while ($row = mysql_fetch_assoc($result)) {
if(rowcount <= 3) {
echo $row['title']
echo $row['pic_title']
echo $row['pic_brief']
} else {
echo $row['title']
echo $row['pic_title']
}
++$rowcount;
}
first query will be like this
"select title, pic_title , pic_brief from table_name order by post_id desc limit 0 , 3"
and rest of five will be
"select title, pic_title from table_name order by post_id desc limit 3 , 5"
second query will exclude the three results returned by first query...
If you want more perfection you can collect all three Ids returned by first query and can add NOT IN in second query.
"select title, pic_title from table_name where post_id not in (1,2,3) order by post_id desc limit 0 , 5";