SQL query in een loop herhaalt voorgaande resultaten

Status
Niet open voor verdere reacties.

jesse123

Gebruiker
Lid geworden
29 aug 2012
Berichten
301
Ik ben bezig met het ontwikkelen van een leerling-volg-systeem waar instructeurs de resultaten op verschillende eisen bij de juiste diploma's kunnen posten. Daarna kunnen de ouders de resultaten bekijken.

Op de bijgevoegde code kunnen de ouders de resultaten zien. $kindid wordt automatisch ingevuld door een GET.

De code werkt perfect, behalve een ding. Iedere keer dat een loop herhaald wordt, worden de resultaten van de voorgaande loops opnieuw weergegeven, en daarna pas de juiste resultaten. (Zie foto)

atStf.png
(Engelse benamingen omdat ik dit ook op stackoverflow gepost heb: https://stackoverflow.com/questions/49004834/sql-query-in-a-loop-cummulates-every-loop)

De eerste twee loops staan in deze afbeelding. Bij de "Opmerking" kun je zien dat de eerste twee resultaten in de tweede loop herhaald zijn van de eerste loop. Bij de derde loop worden zowel de resultaten van de eerste als de tweede loop weergegeven, alvorens de resultaten van het eigen diploma weer te geven.

Hoe kan ik dit maken?

Ik heb geprobeerd om de pointer te resetten (https://stackoverflow.com/questions/10270831/how-do-i-reset-a-php-pointer-for-a-mysql-resource) en ik heb ook geprobeerd om de variable $row te resetten en door unset($row) te gebruiken.

Code:

PHP:
<?

$diplomanumber = 0; //Start bij diploma nummer 0
$i = 0;
$times_to_run = 7; //Aantal diplomas
$array = array();

while ($i++ < $times_to_run)
{ 

$query = "SELECT * FROM Leerlingvolgsysteem WHERE kindid='$kind_id' AND diploma='$diplomanumber' ORDER BY datum DESC;";
$result = mysqli_query($connection,$query);

if(mysqli_num_rows($result) == 0){
    $diplomanumber++; //Geen resultaten, skip naar de volgende loop
    }

    else {  
        echo'<h2 id="'.$diplomanumber.'">';                 //Echo diploma naam
        if($diplomanumber == 0){echo'Spetter Ready';} 
        elseif($diplomanumber == 1){echo'Spetter 1';}
        elseif($diplomanumber == 2){echo'Spetter 2';}
        elseif($diplomanumber == 3){echo'Spetter 3';}
        elseif($diplomanumber == 4){echo'Diploma A';}
        elseif($diplomanumber == 5){echo'Diploma B';}
        elseif($diplomanumber == 6){echo'Diploma C';}
        echo'</h2>';

        while ($row = mysqli_fetch_assoc($result))
        { 
            $phpdate = strtotime($row['datum']);
            $date = date( 'd-m-Y', $phpdate ); //Zet datum om in europees formaat

            $datum .= '<td><b>'.$date.'</b></td>';                              //Defineer alle <td></td> die geloopt worden.
            $eis1 .= '<td class="'.$row['eis1'].'">'.$row['eis1'].'</td>';
            $eis2 .= '<td class="'.$row['eis2'].'">'.$row['eis2'].'</td>';
            $eis3 .= '<td class="'.$row['eis3'].'">'.$row['eis3'].'</td>';
            $eis4 .= '<td class="'.$row['eis4'].'">'.$row['eis4'].'</td>';
            $eis5 .= '<td class="'.$row['eis5'].'">'.$row['eis5'].'</td>';
            $eis6 .= '<td class="'.$row['eis6'].'">'.$row['eis6'].'</td>';
            $eis7 .= '<td class="'.$row['eis7'].'">'.$row['eis7'].'</td>';
            $eis8 .= '<td class="'.$row['eis8'].'">'.$row['eis8'].'</td>';
            $eis9 .= '<td class="'.$row['eis9'].'">'.$row['eis9'].'</td>';
            $eis10 .= '<td class="'.$row['eis10'].'">'.$row['eis10'].'</td>';
            $eis11 .= '<td class="'.$row['eis11'].'">'.$row['eis11'].'</td>';
            $eis12 .= '<td class="'.$row['eis12'].'">'.$row['eis12'].'</td>';

            if(!empty($row['opm'])) {
               $opm .= '<td style="white-space: normal;"><b>'.$row['opm'].'</b></td>';
            }
            else{
                $opm .= '<td style="white-space: normal;">&nbsp;</td>';         // No $opm.
            }

            if(!empty($row['instructeur'])) {
               $inst .= '<td style="white-space: normal;"><b>'.$row['instructeur'].'</b></td>';
            }
            else{
            $inst .= '<td style="white-space: normal;">&nbsp;</td>';            // No $inst
            }

        }

        echo '
        <div class="volgsysteem"><table class="table table-condensed table-bordered neutralize volgsysteem"> 
        <tbody>';                                                                                                   //Start table met div en tbody


        $query2 = "SELECT * FROM Leerlingvolgsysteem_eisen WHERE diploma='$diplomanumber' ORDER BY nr;";                //Query om alle eisen te selecteren

        $result2 = mysqli_query($connection,$query2);
        if(mysqli_num_rows($result2) == 0){
            $diplomanumber++; echo 'Er is een fout opgetreden, waardoor de eisen voor dit diploma niet aan uw kind gekoppeld kunnen worden.</br>';}
        else {
            echo'
            <tr><th class="headcol"><b>Datum:</b></th>'.$datum.'</tr>';
            echo '<th class="headcol"><b>Instructeur</b></th>'.$inst.'</tr>';

                $counter = 0;
                while ($row2 = mysqli_fetch_assoc($result2))    
                {
                    $counter++;         // counter + 1

                    echo '
                    <tr><th class="headcol">'; 

                    echo substr($row2['eis'],0,15);         // Eis afkorten
                    echo '...';

                    $verandernaameisnr = 'eis' . $counter;  // Eisnr hernoemen
                    $eis = $$verandernaameisnr;

                    echo '</th>'.$eis.'';                   // echo demand

                    echo' </tr>';
                }

            echo "<th class='headcol'><b>Opmerking</b></th>";
            echo ''.$opm.'';
            echo' </tr>';
            $diplomanumber++; // Diplomanummer +1
        }

        echo'</tbody>';             //End table
        echo '</table></div> ';

    }

}

?>
 
Laatst bewerkt:
Ik wil echt niet vervelend zijn, of even met de botte bijl op je topic inhakken, maar persoonlijk gezien zou ik toch even terug gaan naar de tekentafel.
De huidige code is dermate onlogisch opgebouwd dat erop voortborduren eindig in een houtje-touwtje oplossing met een hoop plakband.

- Allereerst valt mij po dat je een tabel met de naam Leerlingvolgsysteem. Dit vind ik al vrij sterk, omdat een tabel gelijk is aan een entiteit. Nu likt het mij niet dat je verschillende soorten leerlingvolgsystemen gaat opslaan in de tabel. Hier mis duidelijk een slag met database-normalisatie.

- Ik zie een hoop regels met eisen in je database, waarbij er blijkbaar 12 velden voor gereserveerd zijn in de database. Ook hier wordt niet aan normalisatie gedaan, want het nummeren van velden is uit den boze bij een goede database opzet. Een goede database moet namelijk schaalbaar zijn zodat bij meerdere aantallen van een entiteit geen structuur moet te worden aangepast.

- $kind_id heeft nergens een waarde. Ik zie ook nergens dat dat deze geëscaped wordt. Dus je leerlingvolgsysteem is al meteen eenvoudig te hacken. En met gegevens van personen erin is het helemaal een slechte zaak.

- Een hoop loops in elkaar: Ik vind dit wel apart dat je een hoop loops draait. Een website hoor je eigenlijk met zo min mogelijk queries te draaien, als je een loop hebt met een query, dan wordt die query weer verdubbelt, en als je daarin weer een loop zet om data uit de database te halen voer je dus nog veel meer onnodige queries uit. Een mooi voorbeeld waarbij je database het behoorlijk druk zal krijgen en op een gegevens moment je queries vertraagd kan afhandelen.
De enige oplossing in dit geval is het gebruiken van JOINS. Hiermee kan je twee of meerdere tabellen met elkaar koppelen op grond van bepaalde voorwaarden in de query.

- Wat is nu het nut van dit? echo ''.$opm.'';?
Waarom koppel je lege strings aan een variabele? Je plaatst toch ook geen lege flessen cola weer terug in de koelkast? ;)?

Met andere woorden: Met deze code is weinig mee te beginnen, en begin opnieuw.
 
Hoi, Thanks voor de reactie!

Allereerst moet ik zeggen dat ik het met je eens ben dat het een houtje-touwtje oplossing is, maar had niet het idee dat dat stukje met de loops zo erg was. Goede motivatie om opnieuw te beginnen en inderdaad eens te kijken naar die JOINS! Overigens betreft dit voorlopig nog een testpagina, omdat ik probeer met een speciale layout te werken, maar dat lukte me niet zonder JOINS. :confused:

Om je vragen te beantwoorden:

Allereerst valt mij po dat je een tabel met de naam Leerlingvolgsysteem. Dit vind ik al vrij sterk, omdat een tabel gelijk is aan een entiteit. Nu likt het mij niet dat je verschillende soorten leerlingvolgsystemen gaat opslaan in de tabel. Hier mis duidelijk een slag met database-normalisatie.
Klopt, er worden alleen resultaten in deze tabel gepost, eigenlijk moet de tabel "leerlingvolgsysteem_resultaten" heten ofzo.

Ik zie een hoop regels met eisen in je database, waarbij er blijkbaar 12 velden voor gereserveerd zijn in de database. Ook hier wordt niet aan normalisatie gedaan, want het nummeren van velden is uit den boze bij een goede database opzet. Een goede database moet namelijk schaalbaar zijn zodat bij meerdere aantallen van een entiteit geen structuur moet te worden aangepast.
Jep klopt, daar wilde ik nog een oplossing voor zoeken.

- $kind_id heeft nergens een waarde. Ik zie ook nergens dat dat deze geëscaped wordt. Dus je leerlingvolgsysteem is al meteen eenvoudig te hacken. En met gegevens van personen erin is het helemaal een slechte zaak.
$kind_id wordt zoals benoemd uit een $_GET gehaald, dat stukje staat niet in deze code, maar staat op de pagina wel boven dit stukje code. Escape is een goeie!

- Wat is nu het nut van dit? echo ''.$opm.'';?
Waarom koppel je lege strings aan een variabele? Je plaatst toch ook geen lege flessen cola weer terug in de koelkast? ?
Daar stond eerst nog een stukje tekst voor, en een punt achter, nu zijn ze inderdaad niet meer nodig.
 
Jep klopt, daar wilde ik nog een oplossing voor zoeken.
Dan zou ik bij normalisatie denken aan een koppeltabel. Je hebt dus een hoop eisen. Dit is een entiteit op zich, dus dan maak je een tabel aan die zo heet. Met een koppeltabel kan je de eisen die je per record invoert dan weer koppelen aan de juiste leerlingID's bijvoorbeeld.
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Steun Ons

Nieuwste berichten

Terug
Bovenaan Onderaan