Compare current record with previous record in loop / loop

1

Scenario

Let's say I have 100 records in any BD .

ID | PESSOA | CARRETO | ENDERECO | DISTANCIA
1  |   A    |    C10  |    XX    |    20
2  |   B    |    C20  |    XY    |    25
3  |   D    |    C50  |    XZ    |    19
4  |   D    |    C50  |    XZ    |    19
5  |   F    |    C10  |    XW    |    27
...
...

From a query, I'm going to generate an Array with all these records , and while doing fetch , I need to check some conditions, comparing the previous record of the current record :

  • ID of reg. previous = ID of reg. current -1
  • PESSOA of reg. previous = PESSOA of reg. current
  • CARRETO of reg. previous = CARRETO of reg. current
  • ENDERECO of reg. previous = ENDERECO of reg. current
  • DISTANCIA of reg. previous = DISTANCIA of reg. current

Example:

ID | PESSOA | CARRETO | ENDERECO | DISTANCIA
3  |   D    |    C50  |    XZ    |    19
4  |   D    |    C50  |    XZ    |    19

( If all conditions are true, I write the current record with DISTANCIA = 0 .)

How I did

In the loop I make fetch , I used auxiliary variables to bring and compare the previous record check the conditions, and write the current one in the array:

// variáveis auxiliares:
$id_ant = null; // seto como null para a 1a comparação
$pes_ant; $car_ant; $end_ant; $dis_ant;

while ($row = $result->fetch_assoc()) {

   // verifico as condições
   if ($id_ant == $row['ID']-1 && $pes_ant == $row['PESSOA'] && $car_ant == $row['CARRETO'] && $end_ant == $row['ENDERECO'] && $dis_ant == $row['DISTANCIA'])
       $row['DISTANCIA'] == 0;

   // gravo o registro no array
   $array[] = $row;

   // seto cada variável para depois utilizar na comparação posterior
   $id_ant = $row['ID']; 
   $pes_ant = $row['PESSOA']; 
   $car_ant = $row['CARRETO']; 
   $end_ant = $row['ENDERECO']; 
   $dis_ant = $row['DISTANCIA'];
}

Example how the 4 register in the array would look like:

(
    [ID] => 4
    [PESSOA] => D
    [CARRETO] => C50
    [ENDERECO] => XZ
    [DISTANCIA] => 0
)

Questions

  • What if I had a table with 100 columns to compare? Would you have to do all this one by one or have an "automatic" way to do this?
  • Is it advantageous for me to do this already in fetch or would it be better to throw everything into an Array and then work on it? (thinking about performance)
asked by anonymous 03.08.2018 / 19:17

2 answers

1

Try the example below:

//$array são todos os resultados da query ($result->fetch_all() )

if(count($array) > 1) { //verifica se existem mais de 1 item no array

  foreach ($array as $key => $atual) { //percorre o resultado da query

    if ($key > 0) { //compara se não é o primeiro item, pois este não terá item anterior

        $keyAnterior = $key - 1; //armazena o indice do registro anterior


        $anterior = $array[$keyAnterior]; //pega o item anterior do array

        if ($anterior['id'] == ($atual['id'] - 1)) { //comparar os ids (esta comparação ocorre devido a regra solicitada)

            unset($atual['id'], $anterior['id']); //remove a "coluna" id dos dois valores pois este ja foi comparado acima


            $saoIguais = $anterior === $atual; //compara se as colunas restantes do item anterior e do item atual são identicas

            if($saoIguais){
                //as demais colunas são iguais entre os itens
            }else{
                //as demais colunas são diferentes
            }

        } else {
            //a validação do id anterior == (id atual -1) não é verdadeira
        }
    }
  }
}

EDIT

Using the fetch_assoc method you can try this:

$anterior = null;
while ($row < $result->fetch_assoc()) { //percorre pelo resultado da query
    $atual = $row; //utilizada variavel auxiliar pois o indice id será excluido do array, e precisaremos dele na proxima iteração

    if(!is_null($anterior)) { //verifica se o anterior não é null | primeira iteração
        if ($anterior['id'] == ($atual['id']) - 1) { //verificação do id

            unset($anterior['id'], $atual['id']); //remove o indice do item anterior e do atual

            if ($atual == $anterior) { //compara os indices restantes (podem ter N indices)
                echo "São iguais";
            } else {
                echo "São diferentes";
            }
        }
    }

    $anterior = $row; //atribui a variavel auxiliar ao item anterior
}

** Answer Doubt 1: ** Yes, you can compare N indices with the equality operator (== or ===);

** Resposda Doubt 2: ** According to php. net using the fetch_all () method will consume more memory because it returns all rows at once. In this specific case you still need to iterate each line with a loop, which may actually impact performance. However, for results of a few lines it is imperceptible.

I hope I have helped.

    
03.08.2018 / 20:00
1

Do so

<?PHP 
while ($row = $result->fetch_assoc()) {

   // verifico as condições
   if ($id_ant == $row && $row['ID']==$id_ant['ID']-1){
    $array[] = $row;
   }
   $id_ant = $row;
}
?>
    
03.08.2018 / 23:21