MySQL ORDER BY and while loop

I have already asked a question related to this issue here

The code from RiggsFolly's accepted answer works really correctly, but there is a slight problem with that. It took me several days to test this and was looking for a reason why this is not the best way to solve the main problem. I was pleased to open a new question.

The code from RiggsFolly is based on $current_provider

, so the while-loop checks each round if $current_provider

changed. So far, so good. BUT now I needed to add overarching logic. It looks to me like I added a variable true/false

that just checks if the value from the retrieved object is equal to a specific string. This comparison focuses on a specific list item, not the base one $current_provider

.

Thus, the target $current_provider

checks each selected object for true/false

and does not depend on $current_provider

. At the moment I'm trying to extend the second loop, but just want to give an example in the hope that it will be clear what to achieve:

$service = $db->query("SELECT * FROM `system` ORDER BY provider, artist");
$provider = NULL;
$close = false;

while ($data = $service->fetch_object()) {

    $amount_1 = $data->digit_1; //db-structure: float
    $amount_2 = $data->digit_2; //db-structure: float

    if ($amount_1 == $amount_2) {
        $close = true;
    }
    if ( $current_provider != $data->provider ) {  
        if ( $current_provider !== NULL ) {
            echo '</div>close container in case of current_provider is already set';
        }
        echo '<div class="provider">open a new container in case of current_provider is not like data->provider or empty';
        $current_provider = $data->provider;
    }
    echo 'some styling for each object';   
    if ($close === true ) { 
        echo '<div class="specific">if the amount_1 is same like amount_2 for a single object add only for this object a certain div';  
    } else {
        echo '<div>show standard container even on specific object';
    }   
echo '</div><!--close container provider-->';
}

      

Sincerely.

+1


source to share


2 answers


I'm still not sure I understand what you are actually trying to achieve here, but perhaps if you make a solution like this it will seem more obvious what you might need in addition to what I am suggesting.

Moving

$amount_1 = $data->digit_1; 
$amount_2 = $data->digit_2; 

      



from perfectly good object properties to 2 scalar variables is completely unnecessary, because storing everything twice, you will eventually run out of memory, but more importantly if you leave them in the object and test them using if ($data->digit_1 == $$data->digit_2) {

so that it never gets confused where are these the data came from!

Also testing the digits at the top of the loop just to set a simpler scalar variable used later at the bottom of the loop is a waste of time. These properties don't change between the top and bottom of the loop, so check the actual object where you want to make a decision and then pull the required HTML right there and then. Another potential confusion was averted and 8 to 16 bytes of memory did not go to waste!

$service = $db->query("SELECT * FROM `system` ORDER BY provider, artist");
$current_provider = NULL;

while ($data = $service->fetch_object()) {

    if ( $current_provider != $data->provider ) {  

        if ( $current_provider !== NULL ) {
            echo '</div>close container in case of current_provider is already set';
        }

        echo '<div class="provider">open a new container in case of current_provider is not like data->provider or empty';
        $current_provider = $data->provider;
    }

    echo 'some styling for each object';   


    // at this point we test the 2 digits and if equal
    // add an extra bit of HTML to the output
    if ($data->digit_1 == $data->digit_2) {
        echo '<div class="specific">if the amount_1 same like amount_2 for a single object add only for this object an certain div';  
    } else {
        echo '<div>show standard container even on specific object';
    }   
echo '</div>;
}

      

+2


source


To avoid playing with open and close, it is better to store them in an array and output them at the end.

Look at my example, it's simple:



$service = $db->query("SELECT * FROM `system` ORDER BY provider, artist");
$provider = NULL;
$lines = array();
while ($data = $service->fetch_object()) {
    $close = false;
    if ($something === $another) {
        $close = true;
    }

    if ( $provider != $data->provider ) {  
        $lines[] = '<div class="provider">'.$data->provider.'</div>';
        $provider = $data->provider;
    }

    if ($close === true ) { 
        $lines[] = '<div class="specific">add container for just a specific object when close === true within the while loop</div>';  
    } else {
        $lines[] = '<div>show standard container on specific object</div>';
    }   
}

foreach($lines AS $line) {
    echo $line;
}

      

+2


source







All Articles