首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >执行while /循环以获得10个随机结果

执行while /循环以获得10个随机结果
EN

Stack Overflow用户
提问于 2012-03-30 23:12:02
回答 3查看 2.2K关注 0票数 3

你好,我正在尝试为我的网站做一个标签脚本,这样每次搜索引擎来到我的网站时,10个不同的标签将在我的网站上显示。

这些标签将从数据库中抓取。所以在那一刻,我已经编码好了,所以它只抓取一个。(因为我不知道怎么做while )

就像这样

代码语言:javascript
复制
$sql = "SELECT tagname FROM tags ORDER BY rand() LIMIT 10";
$result = mysql_query($sql);
$row = mysql_fetch_object($result);
echo "<a href='index.php'>" .$row->tagname. " </a>";

有没有什么办法,我可以加上一段时间,这样它就会做10次?例如,使用相同的echo,但打印出10个结果,而不是1....。我已经将限制从1更改为10,但这不起作用...还在放映一个。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-30 23:13:20

注意,在真正的答案之前阅读:对于那些不断否决这个答案的人。阅读标题(以"Doing a while“开头)和最后一部分的问题(”a I can a while to that so it to 10次?")。这个答案是关于迭代结果集的,而不是关于RAND函数的用法!这个问题甚至没有出现在我的答案中,我在最后还建议了一种不同的方法:

您只需要将对mysql_fetch_object的调用包装在一个循环中

代码语言:javascript
复制
$result = mysql_query($sql);

while ($row = mysql_fetch_object($result))
{
echo "<a href='index.php'>" .$row->tagname. " </a>";
}

稍后编辑的其他注意事项包括:

  • 如果表包含非常大量的数据(但看起来并非如此),那么order by

()可能会对使用pdo (或至少

  • )的performance
  • consider产生不良影响即使查询看起来很完美,您也应该进行一些错误处理,至少

if (!$result) { echo mysql_error();die;}

票数 -2
EN

Stack Overflow用户

发布于 2012-03-30 23:43:02

请停止使用ORDER BY RAND(). 别说了。此操作具有n*log2(n)的复杂性,这意味着查询所花费的时间将会增加。

代码语言:javascript
复制
    entries  |  time units
  -------------------------
         10  |         1     /* if this takes 0.001s */
      1'000  |       300
  1'000'000  |   600'000     /* then this will need 10 minutes */

如果要生成随机结果,请创建一个存储过程,该存储过程将生成这些结果。类似这样的代码(取自this article的代码,您应该阅读它):

代码语言:javascript
复制
DELIMITER $$
DROP PROCEDURE IF EXISTS get_rands$$
CREATE PROCEDURE get_rands(IN cnt INT)
BEGIN
  DROP TEMPORARY TABLE IF EXISTS rands;
  CREATE TEMPORARY TABLE rands ( tagname VARCHAR(63) );

loop_me: LOOP
    IF cnt < 1 THEN
      LEAVE loop_me;
    END IF;

    SET cnt = cnt - 1;

    INSERT INTO rands
       SELECT tags.tagname
         FROM tags 
         JOIN (SELECT (RAND()*(SELECT MAX(tags.id) FROM tags)) AS id) AS choices
        WHERE tags.id >= choices.id
        LIMIT 1;

  END LOOP loop_me;
END$$
DELIMITER ;

要使用它,您可以这样写:

代码语言:javascript
复制
CALL get_rands(10);
SELECT * FROM rands;

至于在PHP端执行它,你应该停止使用古老的mysql_*应用程序接口。它已经有10多年的历史了,已经不再维护了。社区甚至有begun process来弃用它们。2012年应该不会有更多的新代码使用mysql_*编写。相反,您应该使用PDOMySQLi。至于如何编写它(使用PDO):

代码语言:javascript
复制
// creates DB connection
$connection = new PDO('mysql:host=localhost;dbname=mydb;charset=UTF-8', 
                      'username', 'password');
$connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

// executes the procedure and creates select statement
$connection->exec('CALL get_rands(10)');
$statement = $connection->query('SELECT * FROM rands');

// performs query and collects all the info
if ($statement->execute())
{
    $tags = $statement->fetchAll(PDO::FETCH::ASSOC);
}

更新

如果要求不仅要获得10个随机结果,而且要实际获得10的唯一随机结果,则需要对PROCEDURE进行两次更改

  1. 临时表应该强制条目的唯一性:

创建临时表rands (标记名VARCHAR(63) UNIQUE);

只收集ID而不收集值也可能是有意义的。特别是如果您要查找的是10篇独特的文章,而不仅仅是标签。

  • 当发现插入重复的值时,cnt计数器不应减少。这可以通过添加一个HANDLER (在LOOP的定义之前)来确保,它将“捕捉”引发的警告,并调整计数器:

为SQLSTATE '23000‘声明CONTINUE处理程序SET cnt = cnt + 1;

票数 27
EN

Stack Overflow用户

发布于 2012-03-30 23:14:41

您只获取了其中的一个

您需要在一段时间内逐个获取所有这些内容

代码语言:javascript
复制
$sql = "SELECT tagname FROM tags ORDER BY rand() LIMIT 10";
$result = mysql_query($sql);
while($row = mysql_fetch_object($result)) {
    echo "<a href='index.php'>" .$row->tagname. " </a>";
}
票数 -3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9945691

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档