简体   繁体   中英

How to echo specific multiple same records only once using foreach loops in PHP?

I have these output using foreach loop in PHP. Right now the output inside foreach is like below.

PHP code

<table>
  <thead>
    <tr>
      <th>ACCOUNT NUMBER</th>
      <th>CATEGORY</th>
      <th>AMOUNT</th>
      </tr>
  </thead>
  <tbody>
    <?php
      $sqlTxt = "SELECT * FROM table WHERE column = 'Fruits' ";
      $sql = ORACLE::getInstance()->FetchArray($sqlTxt);
      if(count($sql) > 0)
      {
        foreach($sql as $row)
        {
    ?>
        <tr>
          <td><?php echo $row["ACCOUNT_NUMBER"] ;?></td>
          <td><?php echo $row["CATEGORY"]; ?></td>
          <td><?php echo $row["AMOUNT"]; ?></td>
        </tr>
    <?php
        }
      }
    ?>
  </tbody>
</table>

And the output for above code is like this

Account Number          Category            Amount
1001                    Apple               30.00
1001                    Mango               30.00
1001                    Blueberry           30.00 

1002                    Durian              40.00
1002                    Pineapple           40.00
1002                    Jackfruit           40.00 
1002                    Lime                40.00

1003                    Lemon               50.00
1003                    Orange              50.00

My questions is how can I echo Account Number and Amount one time only while category keeps the looping ?

My goal is to look like this. To add br tag after each comas.

Account Number          Category            Amount
1001                    Apple,              30.00
                        Mango,              
                        Blueberry            

1002                    Durian,             40.00
                        Pineapple,          
                        Jackfruit,           
                        Lime                

1003                    Lemon,              50.00
                        Orange              

So far, what I have in my code is like this.

PHP Code

<table>
  <thead>
    <tr>
      <th>ACCOUNT NUMBER</th>
      <th>CATEGORY</th>
      <th>AMOUNT</th>
      </tr>
  </thead>
  <tbody>
    <?php
      $sqlTxt = "SELECT * FROM table WHERE column = 'Fruits' ";
      $sql = ORACLE::getInstance()->FetchArray($sqlTxt);
      if(count($sql) > 0)
      {
        $account_numbers = null;
        $categorys       = "";
        $amounts         = null;

        foreach($sql as $row)
        {
          if($row['ACCOUNT_NUMBER'] !== $account_numbers)
          {
            if ($account_numbers !== null)
            {
              echo '</td></tr>';
            }

            echo "<tr>
                    <td>{$row['ACCOUNT_NUMBER']}</td>
                    <td>{$row['CATEGORY']}";
          }
          else {
            echo "<br>{$selectionC['CATEGORY']}";
          }
          $account_numbers = $row['ACCOUNT_NUMBER'];
        }
            echo '  </td>
                  </tr>';
      }
    ?>
  </tbody>
</table>

I'm stuck here. Appreciate if someone can help me to solve this problem.

Thanks.

Try this.

$account_numbers = array();
foreach($sql as $row) {
    $display = FALSE;
    if(!in_array($row["ACCOUNT_NUMBER"], $account_numbers)) {
        $account_numbers[] = $row["ACCOUNT_NUMBER"];
        $display = TRUE;
    } ?>
    <tr>
        <td>
            <?php echo $display ? $row["ACCOUNT_NUMBER"] : ""; ?>
        </td>
        <td><?php echo $row["CATEGORY"]; ?></td>
        <td><?php echo $row["AMOUNT"]; ?></td>
    </tr>
<?php }

Change your query into this one

SELECT *, GROUP_CONCAT(CATEGORY) AS categories
FROM TABLE
WHERE COLUMN = 'Fruits'
GROUP BY ACCOUNT_NUMBER

The full code

<?php
  $sqlTxt = "SELECT *, GROUP_CONCAT(CATEGORY) as categories FROM table WHERE column = 'Fruits' GROUP BY ACCOUNT_NUMBER";
  $sql = ORACLE::getInstance()->FetchArray($sqlTxt);
  if(count($sql) > 0)
  {
    foreach($sql as $row)
    {
?>
    <tr>
      <td><?php echo $row["ACCOUNT_NUMBER"] ;?></td>
      <td><?php echo $row["categories"]; ?></td>
      <td><?php echo $row["AMOUNT"]; ?></td>
    </tr>
<?php
    }
  }
?>

GROUP_CONCAT(CATEGORY) will get all categories according to the ACCOUNT_NUMBER.

Try something like this.

Create new array,reorder and modified it.

PHP

<?php

$arr_old = array(
    0 => array('ACCOUNT_NUMBER' => '1001', 'CATEGORY' => 'Apple', 'AMOUNT' => '30.00'),
    1 => array('ACCOUNT_NUMBER' => '1001', 'CATEGORY' => 'Mango', 'AMOUNT' => '30.00'),
    2 => array('ACCOUNT_NUMBER' => '1001', 'CATEGORY' => 'Blueberry', 'AMOUNT' => '30.00'), 
    3 => array('ACCOUNT_NUMBER' => '1002', 'CATEGORY' => 'Durian', 'AMOUNT' => '40.00'),
    4 => array('ACCOUNT_NUMBER' => '1002', 'CATEGORY' => 'Pineapple', 'AMOUNT' => '40.00'),
    5 => array('ACCOUNT_NUMBER' => '1002', 'CATEGORY' => 'Lime', 'AMOUNT' => '40.00'),
    6 => array('ACCOUNT_NUMBER' => '1003', 'CATEGORY' => 'Lemon', 'AMOUNT' => '50.00'),
    7 => array('ACCOUNT_NUMBER' => '1002', 'CATEGORY' => 'Jackfruit', 'AMOUNT' => '40.00'), 
    8 => array('ACCOUNT_NUMBER' => '1003', 'CATEGORY' => 'Orange', 'AMOUNT' => '50.00')
);

$arr = array();

foreach($arr_old as $key => $item)
{
    if(!array_key_exists($item['ACCOUNT_NUMBER'],$arr)){
        // Add new data in array with ACCOUNT_NUMBER as an index
        $arr[$item['ACCOUNT_NUMBER']][$item['ACCOUNT_NUMBER']]['ACCOUNT_NUMBER'] = $item['ACCOUNT_NUMBER'];
        $arr[$item['ACCOUNT_NUMBER']][$item['ACCOUNT_NUMBER']]['CATEGORY'] = $item['CATEGORY'];
        $arr[$item['ACCOUNT_NUMBER']][$item['ACCOUNT_NUMBER']]['AMOUNT'] = $item['AMOUNT'];
    }else{
        // Only alter category index
        $arr[$item['ACCOUNT_NUMBER']][$item['ACCOUNT_NUMBER']]['CATEGORY'] .= ",".$item['CATEGORY'];
    }


}

ksort($arr, SORT_NUMERIC);

echo "<table>";
echo "<tr>";
echo "<td>ACCOUNT_NUMBER</td>";
echo "<td>CATEGORY</td>";
echo "<td>AMOUNT</td>";
echo "</tr>";
foreach($arr as $key => $item){

    $xpl = explode(",",$item[$key]['CATEGORY']);
    $n_category = "";
    foreach($xpl as $b => $a){
        $n_category .= ($b!=0) ? "<br>".$a : $a ;
    }

    echo "<tr>";
    echo "<td>".$item[$key]['ACCOUNT_NUMBER']."</td>";
    echo "<td>".$n_category."</td>";
    echo "<td>".$item[$key]['AMOUNT']."</td>";
    echo "</tr>";
    // print_r($item);
}
echo "</table>";

And the example here : http://sandbox.onlinephpfunctions.com/code/cfd9579dfe39ab9fba6922209ceec1a33debbfc6

Your entire process of grouping the fruit names and gluing them together with ,<br> can and should be performed in the query as a matter of best practice. Sure, the resultset can be iterated and php functions can be used to prepare the values, but it will be less efficient and result in far more lines of code.

The most direct and professional solution that I can offer you based on your posted details is:

Demo: https://www.db-fiddle.com/f/tWn3qKrpHzV86Yq8k8WhCq/2

SELECT `ACCOUNT_NUMBER`,
        GROUP_CONCAT(`CATEGORY` ORDER BY `CATEGORY` ASC SEPARATOR ',<br>') AS `CATEGORY`,
        MAX(`CATEGORY_AMOUNT`) AS `CATEGORY_AMOUNT`
FROM `table`
WHERE `column` = 'Fruits'
GROUP BY `ACCOUNT_NUMBER`
ORDER BY `ACCOUNT_NUMBER`

Depending on your database settings, you might not need to use MAX() , but for my online demo it was necessary.

Notice that in my demo link, I shuffled the rows and added a vegetable row. If needed for your project, GROUP_CONCAT() also offers DISTINCT if you only want unique values to be grouped together.

If this solution is not suitable for your actual project requirements, then please take the time to update your question details to more accurately reflect what you are working with.

With your resultset fully prepared, you can iterate it normally to display as an html table.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM