Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select random rows from mysqli prepared statement

Tags:

php

I was researching random selection from a MYSQL table. I found out that ORDER BY RAND() is very slow on larger databases. I'm trying to incoorperate a different method but I keep getting a null query on return. I'm not used to the AS statement so perhaps something is wrong with my code?

public function getSmilies( $limit = null, $random = null )
{
    $query = "SELECT find, url, id FROM smilies";
    if($random == 1)
    {
        $query .= " AS r1 JOIN (SELECT (RAND() * (SELECT MAX(id) FROM smilies)) AS id) AS r2 WHERE r1.id >= r2.id ORDER BY r1.id ASC";
    }
    if($limit != null)
    {
        $query .= " LIMIT " . (int)$limit;
    }

    $stmt = $this->link->prepare($query);
    $stmt->execute();
    $stmt->bind_result( $find, $url, $id );
    while($stmt->fetch())
        $row[] = array('find' => $find, 'url' => $url, 'id' => $id );
    $stmt->close();
    return $row;
}

The code works fine when no parameters are passed to the function, but when I add the random parameter it seems to fail.

like image 323
MysteryDev Avatar asked Apr 17 '26 10:04

MysteryDev


1 Answers

MySQL Query:

SELECT * FROM smilies WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM smilies ) LIMIT 5;

Full PHP code:

public function getSmilies( $limit = null, $random = null )
{
    $query = "SELECT find, url, id FROM smilies";
    if($random == 1)
    {
        $query .= " WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM smilies)";
    }
    if($limit != null)
    {
        $query .= " LIMIT " . (int)$limit;
    }

    $stmt = $this->link->prepare($query);
    $stmt->execute();
    $stmt->bind_result( $find, $url, $id );
    while($stmt->fetch())
        $row[] = array('find' => $find, 'url' => $url, 'id' => $id );
    $stmt->close();
    return $row;
}

Note 1: This only works with unique ids.
Note 2: Only tested the MySQL Query, not the PHP code.
Source: http://akinas.com/pages/en/blog/mysql_random_row/ (Solution 3)

EDIT: Another option using PHP.

public function getSmilies( $limit = null, $random = null )
{
    $query = "SELECT find, url, id FROM smilies";
    if($limit != null)
    {
        $query .= " LIMIT " . (int)$limit;
    }
    $stmt = $this->link->prepare($query);
    $stmt->execute();
    $stmt->bind_result( $find, $url, $id );
    while($stmt->fetch())
        $row[] = array('find' => $find, 'url' => $url, 'id' => $id );
    $stmt->close();
    if($random == 1)
    {
        suffle($row);
    }
    return $row;
}
like image 97
Javier Provecho Fernández Avatar answered Apr 19 '26 23:04

Javier Provecho Fernández



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!