How do I not repeat RAND() results in php?

Asked

Viewed 359 times

1

I need to create a simulation that will make a 5 question SELECT randomly.

I’m using the ORDER BY RAND(), but the results are repeated, and I don’t know how I can fix it.

I even created an array that stored the code of each question, but I don’t know how to compare it when doing the SELECT.

Does anyone know how to fix this problem?

The code:

$con = conectar();
$x=1;
for($i=$x; $i<=$x+4; $i++){
 $sql = "SELECT * FROM simulado where cod_disc like 1 order by RAND()";
 $res = mysqlexecuta($con,$sql);
 $row = mysql_fetch_array($res);
 echo $i . ") " . $row['enunciado'];                                 
 $questoes[$i] = $row ['cod_questao'];
}

*The mysqlexecuta method only executes the query and checks for any error in the execution.

  • 4

    ORDER BY RAND itself does not repeat any data. Basically it’s a matter of taking the query out of the loop, because the problem is that you make several Selects and each SELECT you’re reworking the RAND unnecessarily (and changing the sequence, which causes repetition). With a SELECT only multiple records without repeating, just repeat the mysql_fetch_array to get the next one. Besides, your loop is a little complex, so what’s the use of the X? It looks like some kind of pagination, but if so, it needs [Edit] and for the whole problem, as it will also affect the RAND issue

  • Redo the logic of loop for(). Run this query several times straight on your sgbd console and see that Rand() will never repeat itself.

1 answer

3


The ORDER BY RAND() by itself does not repeat any data. It just varies the output order.

Apparently the solution to your case is to take the query loop, because the problem is that you do several SELECTs and each SELECT you are remaking the RAND unnecessarily (and at each moment, the sequence changes, which causes repetition).

With a SELECT only already comes several records without repeating, just keep repeating the mysql_fetch_array to catch the next.

It would be something like this:

$con = conectar();
$x=1;
$sql = "SELECT * FROM simulado where cod_disc like 1 order by RAND()";
$res = mysqlexecuta($con,$sql);

for($i=$x; $i<=$x+4; $i++){
 $row = mysql_fetch_array($res);
 echo $i . ") " . $row['enunciado'];                                 
 $questoes[$i] = $row ['cod_questao'];
}

I noticed that your loop is a little complex, for what it serves the $x? It looks like some kind of pagination, if that is it you need to review the strategy not to repeat between pages. It would be better to use the LIMIT in this case (and a Seed of RAND):

$con = conectar();
$seed = mt_rand(); // Bole um jeito de sortear no primeiro acesso, mas
                   // manter o valor nas páginas seguintes pra não repetir
$pagina = 1;
$itens = 4;
$i = ($pagina - 1) * $itens + 1;

$sql = "SELECT * FROM simulado where cod_disc like 1 order by RAND($seed) LIMIT $i, $itens";

$res = mysqlexecuta($con,$sql);
while($row = mysql_fetch_array($res)) {
    echo $i . ") " . $row['enunciado'];                                 
    $questoes[$i] = $row ['cod_questao'];
    $i++;
}
  • How simple, I’m incredulous! I guess I didn’t quite understand how this mysql_fetch_array worked, but now I got it right. As for the $x, it helps me manipulate FOR. Since the simulator has several categories, I separated each one into a different one, and used $x to store the amount of questions after going through each category. Thank you so much, it worked right!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.