[英]while (mysql_fetch_array) in a while loop
我有此代码:
while ($sum<16 || $sum>18){
$totala = 0;
$totalb = 0;
$totalc = 0;
$ranka = mysql_query("SELECT duration FROM table WHERE rank=1 ORDER BY rand() LIMIT 1");
$rankb = mysql_query("SELECT duration FROM table WHERE rank=2 ORDER BY rand() LIMIT 1");
$rankc = mysql_query("SELECT duration FROM table WHERE rank=3 ORDER BY rand() LIMIT 1");
while ($rowa = mysql_fetch_array($ranka)) {
echo $rowa['duration'] . "<br/>";
$totala = $totala + $rowa['duration'];
}
while ($rowb = mysql_fetch_array($rankb)) {
$totalb = $totalb + $rowb['duration'];
}
while ($rowc = mysql_fetch_array($rankc)) {
$totalc = $totalc + $rowc['duration'];
}
$sum=$totala+$totalb+$totalc;
}
echo $sum;
它可以正常工作,但是问题是直到执行“ echo $ rowa ['duration']”的“ $ sum = 16”为止,问题是,在“ while( $ rowa = mysql_fetch_array($ ranka))“这是while循环吗? 因为大多数时候返回所有数字,直到“ $ sum = 16”
您在第一个内部while循环中显式地回显了$ rowa ['duration']。 如果您只想打印$ ranka集合中的最后一个持续时间,则只需将echo更改为$rowa_duration = $rowa['duration']
然后在循环外回显即可。
while ($rowa = mysql_fetch_array($ranka)) {
$rowa_duration = $rowa['duration'];
$totala = $totala + $rowa['duration'];
}
echo $rowa_duration . '<br/>';
您在这里所做的事情在多个层面上都是不好的。 还有你的英语恐怖。 好..实践使完美。 您可以尝试在FreeNode服务器上加入## php聊天室。 那将提高您的英语和PHP技能。.它肯定对我有很大帮助。 反正..
首先,使用ORDER BY RAND()
非常无知(至多)。 随着表开始变大,此操作将使查询变慢。 它具有n * log2(n)
复杂度,这意味着选择具有1000个条目的查询表将比具有10个条目的查询表花费大约3000倍的时间。
要了解更多信息,您应该阅读此博客文章 ,但是对于您当前的查询,解决方案如下所示:
SELECT duration
FROM table
JOIN (SELECT CEIL(RAND()*(SELECT MAX(id) FROM table)) AS id) as choice
WHERE
table.id >= choice.id
rank = 1
LIMIT 1
这将从表中选择随机duration
。
但是由于您实际上是在选择具有3个不同等级(1、2和3)的数据,因此创建包含三个查询的UNION会很有意义:
SELECT duration
FROM table
JOIN (SELECT CEIL(RAND()*(SELECT MAX(id) FROM table)) AS id) as choice
WHERE
table.id >= choice.id
rank = 1
LIMIT 1
UNION ALL
SELECT duration
FROM table
JOIN (SELECT CEIL(RAND()*(SELECT MAX(id) FROM table)) AS id) as choice
WHERE
table.id >= choice.id
rank = 2
LIMIT 1
UNION ALL
SELECT duration
FROM table
JOIN (SELECT CEIL(RAND()*(SELECT MAX(id) FROM table)) AS id) as choice
WHERE
table.id >= choice.id
rank = 3
LIMIT 1
看起来很吓人,但实际上它会比您当前使用的要快,结果将是“ duration
列中的三个条目。
您仍在使用旧的mysql_*
函数访问数据库。 这种形式的API已有10多年的历史,在编写新代码时不应该使用。 不再维护(修复和/或改进)旧功能,甚至社区也已开始弃用这些功能。
相反,您应该使用PDO或MySQLi 。 使用哪种选项取决于您的个人喜好以及实际可用的选项。 我更喜欢PDO(因为命名参数和对其他RDBMS的支持),但这是一个主观的选择。
php / mysql代码的另一个问题是您似乎毫无意义地循环了思想项目。 您的查询具有LIMIT 1
,这意味着将只有一行。 循环毫无意义。
如果duration
最大值为1
则存在无限循环的可能性。 在循环开始时,您将有$sum === 15
,它适合第一个while
条件。 并且在该循环的最后,您可以拥有$sum === 18
,它满足第二个循环条件...然后它变为无穷大,并且您的SQL Server受阻。
而且,如果您在duration
中使用分数,那么3个新结果的总值需要更小。 刚刚超过2
。 以15.99
开始,以18.01
结尾(持续时间额外增加2.02
或每个持续时间下的0.7
)。 再次..无尽循环。
这是我要怎么做:
$pdo = new PDO('mysql:dbname=my_db;host=localhost', 'username', 'password');
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$sum = 0;
while ( $sum < 16 )
{
$query = 'that LARGE query above';
$statement = $pdo->prepare( $query );
if ( $statement->execute() )
{
$data = $statement->fetchAll( PDO::FETCH_ASSOC );
$sum += $data[0]['duration']+$data[1]['duration']+$data[2]['duration'];
}
}
echo $data[0]['duration'];
这应该执行您的代码所执行的操作..或至少我认为是您的意图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.