Partage
  • Partager sur Facebook
  • Partager sur Twitter

Afficher un tableau croisé dynamique

Afficher un tableau avec nom/nombres de colonnes/lignes inconnues

Sujet résolu
    20 janvier 2020 à 21:07:04

    Bonsoir,

    Je cherche un moyen pour afficher un tableau croisé dynamique. La particularité est donc que je ne sais ni le nom des champs ni le nombre de colonnes ou de lignes.

    Voici la requête SQL :

    SET @sql = NULL;
    SELECT
      GROUP_CONCAT(DISTINCT 
    	CONCAT('COUNT(CASE WHEN VLT.Lieux = ''', VLT.Lieux, ''' THEN IDR ELSE NULL END) AS `', DC_Lieux.Nom, '`')) INTO @sql
    FROM DC_V_Resume_Lieux_Types VLT
    INNER JOIN DC_Lieux ON VLT.Lieux = DC_Lieux.Id;
    SET @sql 
      = CONCAT('SELECT DC_Types.Nom AS Types,COUNT(IDR) AS Total,', @sql, 'FROM DC_V_Resume_Lieux_Types VLT INNER JOIN DC_Types ON VLT.Types = DC_Types.Id INNER JOIN DC_Lieux ON VLT.Lieux = DC_Lieux.Id GROUP BY DC_Types.Nom');
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

    Voici un visuel dans PhpMyAdmin du résultat :

    TCD

    Pour afficher le résultat dans une page PHP, je me suis inspiré de ce sujet, de celui-ci ou encore de celui-là. Voici le début de ma requête :

    <?php
    
    require_once('Requetes/acces.php');     
    $req = $bdd->prepare("CALL ProcVoirStatsTypesLieux()");
    $req->execute();	
    $res = $req->rowCount();
    
    if (!$res)
    {
    	echo '<center><strong>Aucune données accessibles</strong></center>';
    	exit;
    }
    else
    {	
    echo 'lignes : '.$res.'<br />';
    	echo '<table name="Statistiques par Lieux et types">';
    	echo '<caption>Statistiques par Lieux et types</caption>';
    	echo '<thead>';
    	echo '<tr>';
    
        for ($i=0; $i<$req->columnCount(); $i++)
    	{
            $meta = $req->getColumnMeta($i); // Affiche Array
            echo '<th>'.$meta['name'].'</th>';
        }
    	echo '</tr>';
    	echo '</thead>';
    	echo '<tbody>';	

    Jusque-là, ça passe, cela affiche les colonnes. Mais je n'arrive pas à afficher les lignes.

    Si je fais :

    echo '<tr>';
       for ($i=0; $i<$req->rowCount(); $i++)
    	{
    		echo '<td>'.$req[$i].'</td>';
    	}
    	echo '</tr>';

    Cela renvoie l'erreur :

    Fatal error: Uncaught Error: Cannot use object of type PDOStatement as array in C:\wamp64\www\Site DVL Phase 3\DOC200807-TYP.php on line 45

    Si je fais :

    while($donnees = $req->fetch())
    {
    	  echo'<tr>';
      foreach($meta as $colonne)
      {
      
    
              echo'<td>'.$donnees[$colonne['name']].'</td>';
    
      }
        echo'</tr>';
    }

    J'ai l'erreur :

    Warning: Illegal string offset 'name' in C:\wamp64\www\Site DVL Phase 3\DOC200807-TYP.php on line 70

    Et enfin si je mets ceci (que j'ai pris sur le premier lien cité ci-dessus) qui me conviendrait le mieux du point de vue du principe :

       foreach ($req as $valeur)
    	{
            echo '<tr>';
            for ($i=0; $i<count($valeur); $i++)
    		{
    			echo '<td>'.$valeur[$i].'</td>';
            }
            echo '</tr>';
    	}

    Il affiche la première ligne et l'erreur :

    Notice: Undefined offset: 18 in C:\wamp64\www\Site DVL Phase 3\DOC200807-TYP.php on line 56

    En cherchant un peu, j'ai vu que l'erreur "offset" indiquant qu'on avait atteint la valeur $i, mais je n'arrive pas à comprendre comment c'est possible puisque il n'a pas affiché toutes les lignes...

    Est-ce que quelqu'un pourrait, s'il vous plaît, m'orienter vers une piste pour résoudre ce problème. J'ai un peu de mal, malgré les liens consultés, à concevoir une logique pour afficher un tableau "dont on ne sait rien".

    En vous remerciant pour votre aide,

    -
    Edité par KerberosK 20 janvier 2020 à 21:08:13

    • Partager sur Facebook
    • Partager sur Twitter
      22 janvier 2020 à 14:48:43

      Bonjour,

      Donc je suis parti de ce code :

      $req = $bdd->prepare("CALL ProcVoirStatsTypesLieux()");
      $req->execute();	
      $res = $req->rowCount();
      
      if (!$res)
      {
      	echo '<center><strong>Aucune données accessibles</strong></center>';
      	exit;
      }
      else
      {	
      	echo 'lignes : '.$res.'<br />';
      	echo '<table name="Statistiques par Lieux et types">';
      	echo '<caption>Statistiques par Lieux et types</caption>';
      	echo '<thead>';
      	echo '<tr>';
      
          for ($i=0; $i<$req->columnCount(); $i++)
      	{
              $meta = $req->getColumnMeta($i); // Affiche Array
              echo '<th>'.$meta['name'].'</th>';
          }
      	echo '</tr>';
      	echo '</thead>';
      	echo '<tbody>';	
      	
      	
      	echo '<tr>';
      	
      	foreach ($req as $valeur)
      	{
          // detail d'une ligne de resultat
              echo '<tr>';
              for ($i=0; $i<count($valeur); $i++)
      		{
      			
      			echo '<td>'.$valeur[$i].'</td>';
              }
              echo '</tr>';
      		
      	}
      }

      J'ai la ligne d'en-tête et la première ligne des résultats, puis l'erreur :

      Notice: Undefined offset: 18 in C:\wamp64\www\Site DVL Phase 3\DOC200807-TYP.php on line 52

      En faisant un var_dump($req), j'obtiens :

      array (size=36)
        'Types' => string 'Accident' (length=8)
        0 => string 'Accident' (length=8)
        'Total' => string '2' (length=1)
        1 => string '2' (length=1)
        'Tokyo' => string '2' (length=1)
        2 => string '2' (length=1)
        'Shizuoka' => string '0' (length=1)
        3 => string '0' (length=1)
        'Gunma' => string '0' (length=1)
        4 => string '0' (length=1)
        'Kanagawa' => string '0' (length=1)
        5 => string '0' (length=1)
        'Okinawa' => string '0' (length=1)
        6 => string '0' (length=1)
        'Tottori' => string '0' (length=1)
        7 => string '0' (length=1)
        'Nagano' => string '0' (length=1)
        8 => string '0' (length=1)
        'Londres' => string '0' (length=1)
        9 => string '0' (length=1)
        'New York' => string '0' (length=1)
        10 => string '0' (length=1)
        'Transport' => string '0' (length=1)
        11 => string '0' (length=1)
        'Inconnu' => string '0' (length=1)
        12 => string '0' (length=1)
        'Osaka' => string '0' (length=1)
        13 => string '0' (length=1)
        'Tochigi' => string '0' (length=1)
        14 => string '0' (length=1)
        'Yamagata' => string '0' (length=1)
        15 => string '0' (length=1)
        'Hokkaido' => string '0' (length=1)
        16 => string '0' (length=1)
        'Hyôgo' => string '0' (length=1)
        17 => string '0' (length=1)

      Multiplié par 23 lignes. Je comprends mieux le message d'erreur : il y a 18 colonnes (de 0 à 17) et il ne trouve pas la suivante.

      Mais j'ai du mal à voir comment je peux faire pour qu'il passe à la ligne suivante. J'ai essayé de faire une boucle avec un fetch, mais cela ne fonctionne pas non plus.

      Si quelqu'un a une piste, merci.



      -
      Edité par KerberosK 22 janvier 2020 à 14:51:45

      • Partager sur Facebook
      • Partager sur Twitter
        22 janvier 2020 à 14:51:30

        SAlut,

        1) rowcount ne s'utilise pas sur un select (la doc)

        2) pourquoi n'utilises-tu pas foreach pour pacourir les lignes du tableau et les colonnes des lignes ?

        -
        Edité par christouphe 22 janvier 2020 à 14:52:50

        • Partager sur Facebook
        • Partager sur Twitter
          22 janvier 2020 à 19:18:27

          Bonjour,

          Merci pour ta réponse.

          Problème quasi-résolu... C'est en cherchant des réponses sur le rowCount(); que j'ai finalement trouvé le moyen d'afficher tous mes résultats, grâce à ce lien. (une sorte de sérendipité :))

          En fait je restais bloqué au niveau for() voulant afficher ligne par ligne. Et l'imbrication de deux foreach me paraissait improbable mais je comprends la logique du code maintenant.

          Voici le code :

          <?php
          
          require_once('Requetes/acces.php');     
          $req = $bdd->prepare("CALL ProcVoirStatsTypesLieux()");
          $req->execute();	
          $res = $req->rowCount();
          /*if ($req->fetchColumn() <= 0)*/
          if (!$res)
          {
          	echo '<center><strong>Aucune données accessibles</strong></center>';
          	exit;
          }
          else
          {	
          	echo '<table name="Statistiques par Lieux et types">';
          	echo '<caption>Statistiques par Lieux et types</caption>';
          	echo '<thead>';
          	echo '<tr>';
          		 
              for ($i=0; $i<$req->columnCount(); $i++)
          	{
                  $meta = $req->getColumnMeta($i); // Affiche Array
                  echo '<th>'.$meta['name'].'</th>';
              }
          	echo '</tr>';
          	echo '</thead>';
          	echo '<tbody>';	
          
          
          	while ($result = $req->fetch(PDO::FETCH_ASSOC))
          	{
          		$result2[] = $result;
          	}
          	foreach ($result2 as $key => $value)
          	{
          		 echo '<tr>';
          		 foreach ($value as $key2 => $value2)
          		 {
          			  echo '<td>'.$value2.'</td>';
          		 }
          		 echo '</tr>';
          	}
          	echo '</tbody>';
          	echo '</table>';
          }
          ?>

          Pour le rowCount(), c'est un peu plus compliqué. La doc déconseille son utilisation avec SELECT et recommande un SELECT COUNT(*) avec un fetchColumn. Sauf que si je rajoute un COUNT(*) dans ma requête, vu que c'est dynamique, cela va rajouter automatiquement une colonne. Ou alors il faut préciser dans les foreach() de ne pas prendre la première colonne, mais là je c'est, à mon sens, bien au-dessus de mes compétences.

          Merci de m'avoir aidé. :)

          -
          Edité par KerberosK 22 janvier 2020 à 19:19:28

          • Partager sur Facebook
          • Partager sur Twitter
            22 janvier 2020 à 19:21:51

            Et si tu fais 2 requêtes, ce sera plus simple, le count et le select

            • Partager sur Facebook
            • Partager sur Twitter
              23 janvier 2020 à 19:18:30

              Bonsoir,

              Merci pour la suggestion, je vais la faire. Mais je trouve cela bête de devoir faire deux requêtes parce que le rowCount() n'est pas "aux normes" de PHP, surtout que cela fonctionne.

              Merci pour ton aide.

              • Partager sur Facebook
              • Partager sur Twitter

              Afficher un tableau croisé dynamique

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown