1

我想从表中选择随机行并从此处的其他问题中获得以下代码,但我有点困惑将表名和列名放在哪里,因为我以前从未使用 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();
4

2 回答 2

0

看看prepare后有没有报错:

 $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));
} 
于 2013-08-21T23:44:30.717 回答
0

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

阅读评论后,我从这个博客改编了解决方案#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; } } ?>

afaik,这是目前在不同虚拟主机之间具有最佳兼容性的解决方案(从本地迁移到远程主机时,我在使用“get_result”等时遇到了一些问题)。它还考虑到准备好的语句可以以更高的效率重复多次(这是关于 #3 的抱怨之一是它必须重复才能获得多个结果),因此对象被重置并保持活动状态,直到类超出范围或直接调用close。

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

于 2013-10-11T16:54:29.050 回答