选择随机行mysqli

时间:2013-08-21 23:36:42

标签: php mysqli

我想从表中选择随机行,并从其他问题中得到以下代码,但我有点困惑在哪里把表名和列名称作为我从未做过这样的选择之前与mysqli。有人可以帮帮我吗?我的表名是products,列名是title

我得到了:

Fatal error: Call to a member function execute() on a non-object 

以下是代码:

  SELECT name
  FROM random AS r1 JOIN
   (SELECT (RAND() *
                 (SELECT MAX(id)
                    FROM random)) AS id)
    AS r2
 WHERE r1.id >= r2.id
 ORDER BY r1.id ASC
 LIMIT 1

我尝试了什么:

 $mydb = new mysqli('localhost', 'root', '', 'db');
    $stmt = $mydb->prepare("SELECT title
            FROM products AS r1 JOIN
               (SELECT (RAND() *
                 (SELECT MAX(id)
             FROM random)) AS id)
            AS r2
     WHERE r1.id >= r2.id
     ORDER BY r1.id ASC
     LIMIT 1 ");
 $stmt->execute();

2 个答案:

答案 0 :(得分:0)

准备后看看你是否有任何错误:

 $mydb = new mysqli('localhost', 'root', '', 'db');
    $stmt = $mydb->prepare("SELECT title
            FROM products AS r1 JOIN
               (SELECT (RAND() *
                 (SELECT MAX(id)
             FROM random)) AS id)
            AS r2
     WHERE r1.id >= r2.id
     ORDER BY r1.id ASC
     LIMIT 1 ");
if ( false===$stmt ) {
  die('prepare() failed: ' . htmlspecialchars($mydb ->error));
} 

答案 1 :(得分:0)

我最近为我的所有sql函数创建了一个sql驱动程序,获取随机记录就是其中之一。

在阅读完评论之后,我从this blog改编了解决方案#3,这就是我想出来的:

<?php class MyDatabaseDriver { protected $DBC; protected $SEL_RANDOM_OFFSET; protected $SEL_RANDOM_IMAGE; function __construct($uname, $password, $table="my_table") { $this->DBC = new mysqli('localhost', $uname, $password, $table); if ($this->DBC->connect_errno) { printf("Connect failed: %s\n", $this->DBC->connect_error); exit; } $this->initialize(); } function __destruct() { $this->close(); } protected function initialize() { $this->SEL_RANDOM_OFFSET = $this->DBC->prepare("SELECT ROUND(RAND() * COUNT(*), 0) AS `offset` FROM `images` WHERE `albumid` = ?"); $this->SEL_RANDOM_IMAGE = $this->DBC->prepare("SELECT `filename` FROM `images` LIMIT ?, 1"); } function close() { if (!$this->DBC) return; $this->SEL_RANDOM_OFFSET->close(); $this->SEL_RANDOM_IMAGE->close(); $this->DBC->close(); $this->DBC = false; } function SelectRandomImage($gid) { $result = false; $this->SEL_RANDOM_OFFSET->bind_param("i", $gid); $this->SEL_RANDOM_OFFSET->execute(); $this->SEL_RANDOM_OFFSET->bind_result($result); if (!$this->SEL_RANDOM_OFFSET->fetch()) { printf("Select random offset failed: %s\n", $this->SEL_RANDOM_OFFSET->error); $result = false; $this->SEL_RANDOM_OFFSET->reset(); return $result; } $this->SEL_RANDOM_OFFSET->reset(); $this->SEL_RANDOM_IMAGE->bind_param("i", $result); $this->SEL_RANDOM_IMAGE->execute(); $this->SEL_RANDOM_IMAGE->bind_result($result); if (!$this->SEL_RANDOM_IMAGE->fetch()) { printf("Select random image failed: %s\n", $this->SEL_RANDOM_IMAGE->error); $result = false; $this->SEL_RANDOM_IMAGE->reset(); return $result; } $this->SEL_RANDOM_IMAGE->reset(); return $result; } } ?>
<?php class MyDatabaseDriver { protected $DBC; protected $SEL_RANDOM_OFFSET; protected $SEL_RANDOM_IMAGE; function __construct($uname, $password, $table="my_table") { $this->DBC = new mysqli('localhost', $uname, $password, $table); if ($this->DBC->connect_errno) { printf("Connect failed: %s\n", $this->DBC->connect_error); exit; } $this->initialize(); } function __destruct() { $this->close(); } protected function initialize() { $this->SEL_RANDOM_OFFSET = $this->DBC->prepare("SELECT ROUND(RAND() * COUNT(*), 0) AS `offset` FROM `images` WHERE `albumid` = ?"); $this->SEL_RANDOM_IMAGE = $this->DBC->prepare("SELECT `filename` FROM `images` LIMIT ?, 1"); } function close() { if (!$this->DBC) return; $this->SEL_RANDOM_OFFSET->close(); $this->SEL_RANDOM_IMAGE->close(); $this->DBC->close(); $this->DBC = false; } function SelectRandomImage($gid) { $result = false; $this->SEL_RANDOM_OFFSET->bind_param("i", $gid); $this->SEL_RANDOM_OFFSET->execute(); $this->SEL_RANDOM_OFFSET->bind_result($result); if (!$this->SEL_RANDOM_OFFSET->fetch()) { printf("Select random offset failed: %s\n", $this->SEL_RANDOM_OFFSET->error); $result = false; $this->SEL_RANDOM_OFFSET->reset(); return $result; } $this->SEL_RANDOM_OFFSET->reset(); $this->SEL_RANDOM_IMAGE->bind_param("i", $result); $this->SEL_RANDOM_IMAGE->execute(); $this->SEL_RANDOM_IMAGE->bind_result($result); if (!$this->SEL_RANDOM_IMAGE->fetch()) { printf("Select random image failed: %s\n", $this->SEL_RANDOM_IMAGE->error); $result = false; $this->SEL_RANDOM_IMAGE->reset(); return $result; } $this->SEL_RANDOM_IMAGE->reset(); return $result; } } ?>

afaik,这是目前不同webhost之间兼容性最好的解决方案(从本地迁移到远程托管时,我遇到了一些使用'get_result'等问题)。它还考虑到准备好的语句可以重复多次,效率更高(这是关于#3的一个抱怨,它必须重复以获得多个结果)所以对象被重置并保持活着直到class超出范围或者close直接调用。

编辑:在我的OFFSET选择中,我使用“ROUND”,因为我的数据库ID列以1开头,如果您的ID列以0开头,您可能想要使用“FLOOR”