SQL如果随机结果的值小于X,则返回更多随机结果,直到达到X值?

时间:2013-06-19 18:05:12

标签: php mysql sql random

我有一个表(MySql),其中一列是介于-3和3之间的“值”。 我想要做的是:

  1. 如果“Value”是一个正数(1到3,在我的情况下 - 负值将用于其他内容并且在这里不相关),从表中拉一个随机行
  2. 如果“值”为3,则仅显示该行。
  3. 如果“值”为2,则显示该行以及“值”为1的另一个随机行。
  4. 如果“值”为1,则显示该行,再显示一行“值”为2的行,或另外两行,其中“值”为1。
  5. 或者,换句话说,我需要列出行,直到它们的总值为3 - 由一行值为3,两行值为1和2(或2和1)完成,或三行,每行值为1。

    这就是我所拥有的:

    $query = "SELECT * FROM $usertable WHERE Value>0 ORDER BY RAND() LIMIT 1"; //from all positive Values, get one at random
    $query2 = "SELECT * FROM $usertable WHERE Value BETWEEN 1 AND 2 ORDER BY RAND() LIMIT 1"; //from all Values between 1 and 2, get one at random
    $query3 = "SELECT * FROM $usertable WHERE Value=1 ORDER BY RAND() LIMIT 1"; //from all Values equal to 1, get one at random
    $result = mysql_query($query);
    $result2 = mysql_query($query2);
    $result3 = mysql_query($query3);
    
    while($row = mysql_fetch_array($result)) 
        {
      echo $row['A'] . " " . $row['B'] . " " . $row['C'] . " " . $row['Value'];
      echo "<br>";
        }
    while($row['Value']<3) 
        {
       while($row2 = mysql_fetch_array($result2)) 
            {
        echo $row2['A'] . " " . $row2['B'] . " " . $row2['C'] . " " . $row2['Value'];
        echo "<br>";
            }
        }
    while($row['Value'] + $row2['Value']<3)
        {
        while($row3 = mysql_fetch_array($result3)) 
            {
            echo $row3['A'] . " " . $row3['B'] . " " . $row3['C'] . " " . $row3['Value'];
            echo "<br>";
            }
        }
    

    我试图将while语句放在不同的顺序中,并且我不断出现意外的T_WHILE错误。

    我现在拥有它的方式,代码将运行并因此错误而超时: “致命错误:超过30秒的最大执行时间” 并且它不能满足我的需要(如果第一个“值”为3,它仍然会拉动结果。)

    有谁可以指出我做错了什么?必须有一种更好的方法来实现这种情况,而不是我正在做的事情,但我只是没有看到它。有人能用正确的方式指出我吗?谢谢!

3 个答案:

答案 0 :(得分:2)

您可以在SQL中执行此操作。诀窍是处理你有2 + 2的情况。你必须忽略第二个。

以下通过定义@sum变量来处理此问题。根据需要增加value,只需扭转一次。如果值未命中3,则忽略该行:

select t.*,
       @sum := if(@prevsum := @sum < 3 and @sum + value > 3, @sum, @sum + value) as thesum
from (select *
      from t
      where value > 0
      order by RAND()
     ) t cross join
     (select @sum := 0, @prevsum := 0) const
having (@sum - value) <= 3 and (@prevsum <> @sum)

这样可以保留@prevsum,因此它知道忽略“2 + 2”或“1 + 1 + 2”等情况下的最后一行。

答案 1 :(得分:0)

您的while($row['Value'] < 3)循环永远不会结束,因为您永远不会更改$row

我会建议这样的事情:

$first = mysql_fetch_assoc(mysql_query("select * from `".$usertable."` where `Value`>0 order by rand() limit 1"));
$result = array($first);
switch($first['Value']) {
case 1:
    $val = rand(1,2);
    $rows = 3-$val; // 2 if $val is 1, 1 if $val is 2
    $q = mysql_query("select * from `".$usertable."` where `Value`=".$val." order by rand() limit ".$rows);
    while($r = mysql_fetch_assoc($q)) $result[] = $r;
    break;
case 2:
    $result[] = mysql_fetch_assoc(mysql_query("select * from `".$usertable."` where `Value`=1 order by rand() limit 1"));
    break;
// case 3 does nothing special
}
// result rows are in $result[] array.

答案 2 :(得分:0)

你的mysql_query是错误的地方。

您应该意识到,该查询是在调用mysql_query的位置执行的,因此您可以一次又一次地在同一行中循环...

这就是为什么你得到最多的执行时间...

修改

$query = "SELECT * FROM $usertable WHERE Value>0 ORDER BY RAND() LIMIT 1"; //from all positive Values, get one at random
$query2 = "SELECT * FROM $usertable WHERE Value BETWEEN 1 AND 2 ORDER BY RAND() LIMIT 1"; //from all Values between 1 and 2, get one at random
$query3 = "SELECT * FROM $usertable WHERE Value=1 ORDER BY RAND() LIMIT 1"; //from all Values equal to 1, get one at random


$result = mysql_query($query);
$row = mysql_fetch_array($result);
echo $row['A'] . " " . $row['B'] . " " . $row['C'] . " " . $row['Value'];
echo "<br>";

if ($row['Value'] < 3)
{
    switch($row['Value'])
    {
        case 2: //If the "Value" is 2, display that row, plus another random row with a "Value" of 1. - thats your query3
            $result3 = mysql_query($query3);
            $row3 = mysql_fetch_array($result3);
            echo $row3['A'] . " " . $row3['B'] . " " . $row3['C'] . " " . $row3['Value'];
            break;

        case 1: //If the "Value" is 1, display that row, plus either one more row with a "Value" of 2, or 2 more rows each with a "Value" of 1. - your query2
            $result2 = mysql_query($query2);
            $row2 = mysql_fetch_array($result2);
            echo $row2['A'] . " " . $row2['B'] . " " . $row2['C'] . " " . $row2['Value'];
            if($row2['Value'] == 1)
            { //select another row with value of 1 - your query3
                $result3 = mysql_query($query3);
                $row3 = mysql_fetch_array($result3);
                echo $row3['A'] . " " . $row3['B'] . " " . $row3['C'] . " " . $row3['Value'];
            }
            break;
    }
}

请注意,此代码可以多次选择一行 - 您没有提及,行应该是唯一的。如果您需要唯一的行,则需要更改sql代码以不选择所有已选择的行(即通过某些唯一标识符或返回的完整结果集)