【问题标题】:php mysql: remember previous RAND()php mysql:记住以前的 RAND()
【发布时间】:2023-04-02 15:06:01
【问题描述】:

我有这个查询,它从数据库中获取 2 个随机行:

  $query  = "SELECT * FROM foo ORDER BY RAND() LIMIT 2";
  $result = mysql_query($query);

我想要的是记住 2 个选定的项目,以便它们可以在下一页上再次显示,我的想法是通过使用 RAND() 信息更新另一个表来完成,但为了我的一生想不出怎么做,也找不到怎么做的信息。

编辑: 总体思路是显示 2 个新项目以及最后 2 个项目。

编辑 2:

好的,看起来需要使用 SESSIONS 来完成,到目前为止我已经想出了这个,但结果是当前的项目信息,而不是以前的

$item_array = array($item_id);
$_SESSION['lastitems'] = $item_array;

foreach($_SESSION['lastitems'] as $key=>$value) {
 echo $value . ' <br />';
}

问题是我认为 $item_id 实际上是 $row['itemid'] 并且只能从 while 循环中调用,因此像我之前所说的 SESSIONS 是当前项目信息而不是以前的我如何“存储”所以要显示以前的?

编辑 3:我将上面的 foreach 卡在循环之外,但它只返回 1 个项目

【问题讨论】:

  • 不可能。 order by rand() 为在准备结果集时做出的EVERY 排序决策生成一个新的随机数。这不是一个贯穿整个操作的数字。
  • 查看我对 Fluffeh 的第一条评论
  • 请注意order by rand()即使有限制也是一个非常慢的操作,特别是如果你使用一个大表,MySQL仍然会读取整个表,然后将返回的结果限制为一条记录。
  • 您有什么建议可以替代我的查询?

标签: php mysql session


【解决方案1】:

您无法在随后的两个页面中获得相同的 order by rand() - 这就是首先按 rand 排序的重点。

如果您想记住下一页上的数据,为什么不将输出粘贴到$_SESSION 并在那里简单地引用它?

话虽如此,您可以rand() 函数播种一个类似于order by rand(3) 的值,这将为您提供相同的结果 - 但这会打开蠕虫罐将需要开始将相同的种子传递给其他页面 - 您可能必须将其存储在 $_SESSION 中,因此您最终会进入第一格。

编辑:如果您想添加 2 个新项目,请按原样使用您的查询,并继续将数据插入到 $_SESSION 变量中。你可以在那里存储数组,所以它应该很有魅力。拉回数据,将其添加到会话中,显示会话的所有结果。下一页,获取两个新结果,添加到会话,显示会话的所有结果。

编辑 2:

首先,确保在每个页面上都开始会话:

session_start();

您想像对待任何其他数组一样对待$_SESSION 数组:

$query  = "SELECT * FROM foo ORDER BY RAND() LIMIT 2";
$result = mysql_query($query);

不确定在输出之前如何迭代结果,因此请按您认为合适的方式应用:

howeverYouLoopYouQueryResults
{
    $_SESSION['lastitems'][]=$rowFromYourResult;
    // This appends the row to the end of the array
}

现在,当您开始显示数据时,您可以执行以下操作:

foreach($_SESSION['lastitems'] as $key=>$value) {
    echo $value . ' <br />';
    // Keep in mind that it will be storing ALL the 
    // items from the row because you used 'select *'
    // You can see what you selected with:
    print_r($_SESSION['lastitems'];
}

【讨论】:

  • 我知道你不能在随后的两个页面上得到相同的结果,这个想法是显示 2 个新项目以及最后 2 个项目,我不知道会话会如何完成了吗?
  • @Fluffeh:您不将其存储到会话中,您对我的解决方案有何看法?这个想法是随机化顺序,然后在以下查询中使用它。
  • @Fluffeh 感谢代码,它的工作,但有一个问题它没有清除它刚刚添加的先前结果,但通过在 foreach 循环后添加 unset($_SESSION['lastitems']); 解决了问题。
【解决方案2】:

一般来说,如果您想随机化订单然后使用该订单,您只需将订购信息保存在表格中即可。只要确保很少执行第一个查询,因为它会改变顺序。第二个查询只是根据之前确定的顺序拉取数据。

第一个查询可以将随机排序保存到其中一列中:

UPDATE `foo` SET `ordering`=RAND();

然后在订购时使用它:

SELECT * FROM `foo` ORDER BY `ordering`;

【讨论】:

  • 这可以工作,但这意味着如果另一个用户触发update 语句,它会阻止第一个用户的下一个显示?将 mysql rand() 函数播种到每个用户返回相同的结果不是更好吗?
  • @Fluffeh:假设这不依赖于用户,因此用户不应触发重新排序。这样您就不必跟踪用户,并且如果用户清除会话,解决方案也不会失败(当然您可以使用 Evercookie,但您可能希望避免这种情况)。您可以根据您(所有者)定义的基础随机更改顺序,而无需在会话中存储大量数据。
  • 是的,公平的选择。我会为你 +1,但我很久以前就已经这样做了。我猜这是给猫剥皮的众多方法之一——每个人都会选择他们最喜欢的方法:)
  • @Fluffeh:是的,在我看来,这实际上取决于你给猫剥皮的目的。这两种方式各有不同,但各有优劣。无论如何,谢谢;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多