我有这段代码:
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;
它工作正常,但问题是直到“$ sum = 16”“echo $ rowa ['duration']”执行,问题是,是否有“回显”只有最新执行的代码“while($ rowa = mysql_fetch_array($ ranka))”我这个循环? 因为大多数时间都返回所有数字,直到“$ sum = 16”
答案 0 :(得分:2)
您在第一个内部while循环中显式回显$ rowa ['duration']。如果您只想打印$ ranka集中的最后一个持续时间,只需将回显更改为$rowa_duration = $rowa['duration']
,然后在循环外回显。
while ($rowa = mysql_fetch_array($ranka)) {
$rowa_duration = $rowa['duration'];
$totala = $totala + $rowa['duration'];
}
echo $rowa_duration . '<br/>';
答案 1 :(得分:2)
你在做什么在多个层面都很糟糕。你的英国人很可怕。嗯......练习很完美。您可以尝试在FreeNode服务器上加入## php聊天室。这将提高你的英语和PHP技能..它确实帮助了我很多。无论如何..
首先,使用ORDER BY RAND()
非常无知(充其量)。随着您的表开始变大,此操作将使您的查询变慢。它具有n * log2(n)
复杂度,这意味着选择具有1000个条目的查询表将比使用10个条目查询表需要大约3000倍。
要了解有关它的更多信息,请阅读this blog post,但对于您当前的查询,解决方案如下:
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年,不应使用。旧功能不再维护(修复和/或改进),甚至社区已开始process of deprecating所述功能。
相反,您应该使用PDO或MySQLi。使用哪一个取决于您的个人偏好以及实际可用的内容。我更喜欢PDO(因为命名参数和对其他RDBMS的支持),但这有点主观选择。
你的php / mysql代码的其他问题是你似乎无意义地循环思考项目。您的查询有LIMIT 1
,这意味着只有一行。没有必要制作一个循环。
如果duration
的最大值为1
,则可能会出现无限循环。在循环开始时,您将$sum === 15
符合第一个while
条件。并且在循环结束时,您可以拥有$sum === 18
,它满足第二个循环条件......然后它将关闭到无穷大并且您的SQL服务器会阻塞。
如果您使用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'];
这应该做你的代码所做的......或者至少,我认为,是你的意图。