Jump to content

Apresentar dados agrupados por categoria


Recommended Posts

Posted

Boa noite amigos.

Tenho uma página web para apresentar os dados da tabela, os quais deverão ser separados por categoria e uso o seguinte código:

<div class="container" style="align-items:center;  width:90%">
            <?php
            $categorias = mysqli_query($conectar, "SELECT * FROM tbl_cateventos ORDER BY idcatevento ASC");
            $linhas2 = mysqli_fetch_array($categorias);
            $total = mysqli_num_rows($categorias);
            $i = 1;

            while ($i <= $total) :
                $catdesc = mysqli_query($conectar, "SELECT * FROM tbl_cateventos WHERE idcatevento=$i");
                $catresulta = mysqli_fetch_array($catdesc);
            ?>
                <div class="heading">
                    <h1> <?php echo $catresulta['descatevento'] . ' - ' . $i ?> </h1>
                </div>
                <?php
                $sql = mysqli_query($conectar, "SELECT * FROM tbl_menueventos WHERE categoria=$i ORDER BY descritivo ASC");
                ?>

                <table id="example" class="table table-striped table-bordered">
                    <thead>
                        <tr>
                            <th>Descritivo</th>
                            <th>Preço por unidade</th>
                            <th>Preço por pessoa</th>
                            <th>Preço por Kg</th>
                            <th>Tabuleiro p/ 4 pessoas</th>
                            <th>Tabuleiro p/ 6 pessoas</th>
                            <th>Tabuleiro p/ 10 pessoas</th>
                            <th>Tabukeiro p/ 15 pessoas</th>
                            <th>Mínimo para encomenda</th>
                        </tr>
                    </thead>
                <?php

                while ($linhas = mysqli_fetch_array($sql)) :
                    echo "<tr>";
                    echo "<td>" . $linhas['descritivo'] . "</td>";
                    echo "<td>" . $linhas['unidade'] . "</td>";
                    echo "<td>" . $linhas['pessoa'] .  "€" . "</td>";
                    echo "<td>" . $linhas['kg'] . "€" . "</td>";
                    echo "<td>" . $linhas['tab4'] .  "€" . "</td>";
                    echo "<td>" . $linhas['tab6'] .  "€" . "</td>";
                    echo "<td>" . $linhas['tab10'] .  "€" . "</td>";
                    echo "<td>" . $linhas['tab15'] .  "€" . "</td>";
                    echo "<td>" . $linhas['minimo'] . "</td>";
                endwhile;
                $i++;
            endwhile;
                ?>
                </table>
        </div>

Acontece que os dados são apresentados, mas os dados referentes ao código do primeiro evento aparecem associados ao segundo código e assim sucessivamente, sendo que os dados referentes ao último código não são apresentados.

 

Posted (edited)

Boas!

Tenho algumas dicas para ajudar-te.

1. Troca a ordem destas duas funções:

            $linhas2 = mysqli_fetch_array($categorias);
            $total = mysqli_num_rows($categorias);

2. Tens de correr tantas vezes a função "mysqli_fetch_array" quanto o número de resultados. O melhor será colocar num ciclo while:

while($linhas2 = mysqli_fetch_array($categorias)) // devolve um array ou nulo

Se tiveres 3 categorias na tabela, o ciclo while irá correr 3 vezes.

 

3. Como o ID da categoria pode não corresponder à variável $i, recomendo mudares para:

$rs_eventos = mysqli_query($conectar, "SELECT * FROM tbl_menueventos WHERE categoria={$linhas2['id']} ORDER BY descritivo ASC");

while($resultado = mysqli_fetch_assoc($rs_eventos)) {
 // código correspondente à tabela 
}

4. Este fazes se quiseres, porque é uma optimização.

Terás um código mais eficiente se retirares todas as queries dos ciclos while.

Exemplo:

<?php

$resultados = array();
$sql = "SELECT * FROM tabela_categorias ORDER BY data_categoria"; //
$rs_categoria = mysqli_query($sql);

while($row = mysqli_fetch_assoc($rs_categoria)) {
 $resultados[ $row['id'] ] = array(); 
}

if(!empty($resultados)) {
  $ids_categorias = array_keys($resultados); // também podes usar directamente a função no implode
  $sql_eventos = "SELECT * FROM eventos WHERE id_categoria IN (" . implode(', ', $ids_categorias) . ") ORDER BY id_categoria, data_evento";
  $rs_eventos =  mysqli_query($sql_eventos);
  
  while($row = mysqli_fetch_assoc($rs_categoria)) {
 	$resultados[ $row['id_categoria'] ][] = $row; 
  }
}

// 'Total categorias: ' . count($resultados);

foreach($resultados as $id_categoria => $rows) {
  // 'Total eventos: ' . count($rows);
  foreach($rows as $row) {
     // código relativo à tabela 
  }
}

Desta forma corres duas queries, e terás resultados em menos tempo

Edited by MasterG
  • Vote 1
Posted

Obrigado @MasterG pela resposta.

Testei como disseste, mas ou não percebi bem ou o que disseste para fazer também não funcionou-

 

Com o código que coloquei anteriormente aparece assim, mas o que deveria aparecer era como as setas vermelhas indicam.

A formatação UTF8 está a ser corrigida.

Posted

Olá!

Função currency:

function currency($value)
{
  $formatter = new NumberFormatter('pt_PT', NumberFormatter::CURRENCY);
  return  $formatter->formatCurrency($value, 'EUR');
}


Escrevi a query assim:

$query = 'SELECT
    E.*,
    M.*

    FROM tbl_menueventos M

    left join tbl_cateventos E on E.idcatevento = M.categoria

    ORDER BY idcatevento ASC';

Agrupei o resultado assim:

$grouped = [];
    foreach ($result as $row) {
      $grouped[$row['descatevento']][] = $row;
    }

    return $grouped;

Exibi a tabela assim:

<?php
  foreach ($menuData as $categoria => $options) {
    ?>
    <div class="heading">
      <h1> <?php echo $categoria ?> </h1>
    </div>

    <table id="example" class="table table-striped table-bordered">
      <thead>
        <tr>
          <th rowspan="2">Descritivo</th>
          <th colspan="3" class='bg-price'>Preço por</th>
          <th colspan="4" class='bg-board'>Tabuleiro para </th>
          <th rowspan="2">Mínimo<br>para<br>encomenda</th>
        </tr>
        <tr>
          <th class='bg-price'>unidade</th>
          <th class='bg-price'>pessoa</th>
          <th class='bg-price'>Kg</th>
          <th class='bg-board'>4 pessoas</th>
          <th class='bg-board'>6 pessoas</th>
          <th class='bg-board'>10 pessoas</th>
          <th class='bg-board'>15 pessoas</th>
        </tr>
      </thead>
      <?php

        foreach ($options as $v) {
          echo '<tr>'
            . '<td>' . $v['descritivo'] . '</td>'
            . '<td>' . currency($v['unidade']) . '</td>'
            . '<td>' . currency($v['pessoa']) . '</td>'
            . '<td>' . currency($v['kg']) . '</td>'
            . '<td>' . currency($v['tab4']) . '</td>'
            . '<td>' . currency($v['tab6']) . '</td>'
            . '<td>' . currency($v['tab10']) . '</td>'
            . '<td>' . currency($v['tab15']) . '</td>'
            . '<td>' . $v['minimo'] . '</td>'
            . '</tr>';
        }
    ?>
    </table>
  <?php
  }
  ?>

Obtive esse resultado:
P-UoObgeQIqSekSKbLLdyA.png

Supondo que o database seja assim:

drop schema if exists pap;
create schema pap;
use pap;

create table tbl_cateventos(
	idcatevento int(9) auto_increment primary key,
	descatevento varchar(198)
)Engine=InnoDB;

insert into tbl_cateventos(descatevento) values ('Carnes'), ('Entradas'), ('Entradas 2'), ('Peixes, Mariscos e Crustáceos');

create table tbl_menueventos(
idmenueventos int(9) auto_increment primary key,
categoria int(9),
descritivo text,
unidade varchar(198),
pessoa varchar(198),
kg decimal(14,5),
tab4 decimal(14,5),
tab6 decimal(14,5),
tab10 decimal(14,5),
tab15 decimal(14,5),
minimo int(3),
constraint foreign key(categoria) references tbl_cateventos(idcatevento)
)Engine=InnoDB;

insert into tbl_menueventos(descritivo, categoria, pessoa, kg, tab4, tab6, tab10, tab15, minimo) VALUES
('Carnes', 1, .5, 30, 6, 8, 14, 20, 2),
('Entradas 2', 2, .5, 25, 4, 6, 12, 18, 1),
('Entradas', 2, null, null, null, null, null, null, 1);

 

  • Vote 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.