Partage
  • Partager sur Facebook
  • Partager sur Twitter

Modification d'une requête pour rajout de données

suite du post un ou plusieurs tables

Sujet résolu
    11 mai 2022 à 22:28:39

    Bonjour, j'ai actuellement ce code qui m'affiche le poids et la température de 6 ruches : avec 2 tables une liste_Ruches contenant le numéro de ruche (id_ruche) et son nom

    et une autre table telemesures_ruches contenant les informations reçues pour chaque ruche

    <!DOCTYPE HTML>
    <!--
    	Editorial by HTML5 UP
    	html5up.net | @ajlkn
    	Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
    -->
    <html lang="fr">
    
    	<head>
    		<title>Les ruches de Gilles</title>
    		<meta charset="utf-8" />
    		<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
    		<link rel="stylesheet" href="assets/css/main.css" />
    	</head>
    	<body class="is-preload">
    	<h1> <CENTER>Les ruches de Gilles </CENTER></h1>		<!-- Titre de la page centré -->
    		<!-- Wrapper -->
    			<div id="wrapper">
    
    				<!-- Main -->
    					<div id="main">
    						<div class="inner">
    
    														<!-- Header -->
    								<header id="header">
    									<a href="index.php" class="logo"><strong>Recharger cette page</strong></a>
    
    								</header>
    
    							<!-- Content -->
    								<section>
    									<header class="main">
    								<span class="image main"><img src="images/ruche.png" alt="" /></span>	
    			
    									</header>
    												
    
    										<h1>Dernières données remontées</h1>
    				
    						
    
    
    
    <?php
    error_reporting(E_ALL);
    ini_set('display_errors', TRUE);
    ini_set('display_startup_errors', TRUE);
    
    $sDatabase = 'ruches';
    $sHostIP = '127.0.0.1';
    $sUser = 'abeille';
    $sPwd = 'password';
     
    $sDSN = 'mysql:dbname='.$sDatabase.';host='.$sHostIP;
    
    // Connexion MySQL 
    try {
        $bdd = new PDO($sDSN, $sUser, $sPwd);
    
    // Activation des erreurs PDO
     $bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    // mode de fetch par défaut : FETCH_ASSOC / FETCH_OBJ / FETCH_BOTH
    
     $bdd->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
        } catch (PDOException $e) {
        echo 'Connexion échouée : ' . $e->getMessage();
    			      } 
    
        
      
         
        // Liste de toutes les ruches
        $requete1 = $bdd->query('SELECT * FROM Liste_ruches');
        $ruches = $requete1->fetchAll();
         
        // Listes des mesures
    
    
    $requete = $bdd->query('SELECT DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ) AS horodatage, M.id_ruche, ROUND(AVG(M.mas),2) AS poids, ROUND(AVG(M.tex),2) AS temperature
    			FROM Telemesures_ruches M INNER JOIN Liste_ruches R ON M.id_ruche = R.id_ruche
    			WHERE DATE (horodatage) >= NOW() - INTERVAL 50 DAY GROUP BY DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ),
        			M.id_ruche ORDER BY DATE_FORMAT( M.horodatage, "%Y-%m-%d %H:00" ) DESC');
    
    $mesures = $requete->fetchAll();
    
    
    /*requete création menu */
    
    $sSql = "SELECT id_ruche, nom FROM Liste_ruches ORDER BY id_ruche ASC";
    
    
    
    $rResult = $bdd->query($sSql);
    $aData = $rResult->fetchAll();
    
    //echo 'il y a '.count($aData).' entrées.';	// affichage du nombre d'entrée de la table les_ruches
    
    
    $aMenuPrincipal = []; // préparer le menu en tableau
    
    $Regroupement = [];	// préparation d'un tableau pour regrouper les données issues de plusieurs ruches
    
    
    
    
    
    foreach ($aData as $donneesMenu)
    {
    //echo '<tr><th>'.$donneesMenu['id_ruche'].'</th><th>'.$donneesMenu['nom'].'</th></tr>';			// affichage du contenu de la table les_ruches
    
    
          $aMenuPrincipal[] = array('id' => $donneesMenu['id_ruche'],'nom' => $donneesMenu['nom']);	// remplissage du tableau $aMenuPrincipal à partir de la table les_ruches
      								       
    }
    
    /* fin requete création menu */
    
    
         
        // Si il y a des ruches et des mesures on affiche le tableau
        // Sinon on affiche un message "aucune données"
        if( count( $ruches ) && count( $mesures ) ) {
    ?>
        <table>
    
            <thead>
                <tr>
                    <th>Date</th><th>T° rucher</th>
    <?php
            // Une entête de colonne par ruche
            foreach( $ruches as $ruche ) {
    ?>
                                        <th><?= $ruche['nom']; ?></th>
    <?php
            }
    ?>
                                    </tr>
                                </thead>
    
                                <tbody>
    <?php
            // On construit le tableau 2D
            $donnees = array();
    
    foreach( $mesures as $mesure ) {
    				/*$donnees[$mesure['horodatage']][$mesure['id_ruche']] = $mesure['valeur'];*/
        				$donnees[$mesure['horodatage']][$mesure['id_ruche']] = ['poids' => $mesure['poids'],'temperature' => $mesure['temperature']];
    				}
    
    
            // On boucle sur le 2D pour afficher les lignes
            foreach ( $donnees as $date => $mesures ) {
    ?>
                                    <tr>
                                        <td><?= $date; ?></td>
    <?php
            foreach( $ruches as $ruche ) {
    ?>
                                        <td>
    <?php
    			/* boucle d'affichage des données*/
              /*  foreach( $mesures as $id => $valeur ) {
                    if( $id == $ruche['id_ruche'] ) echo $valeur;
                }*/
    		foreach( $mesures as $id => $valeur ) {
        		if( $id == $ruche['id_ruche'] ) {
            	echo '<ul>';
           		echo '<li>Poids : '.$valeur['poids'].'</li>';
            	echo '<li>Temp. : '.$valeur['temperature'].'</li>';
           		echo '</ul>';
        }
    }
    
    ?>
                    </td>
    <?php
            }
    ?>
                </tr>
    <?php
        }
    ?>
            </tbody>
        </table>
    
    <?php
        } else {
    ?>
        <p>Aucune données à afficher.</p>
    <?php
        }
    
    
    ?>
    <!--Affichage menu -->								
    
    						</div>
    					</div>
    
    				<!-- Sidebar -->
    					<div id="sidebar">
    						<div class="inner">
    
    
    							<!-- Menu -->
    								<nav id="menu">
    									<header class="major">
    										<h2>Menu</h2>
    									</header>
    
     <?php if (count($aMenuPrincipal) > 0) { ?>
    
    
        <ul>
    
        <?php
        foreach ($aMenuPrincipal as $iLine => $aMenu) {
            $sLink = 'indexa.php?ruche='.$aMenu['id'].'&p=';
            echo '<li>
                <span class="opener">'.$aMenu['nom'].'</span>
                	<ul>
                    <li><a href="'.$sLink.'donnees"> DONNEES </a></li>
                    <li><a href="'.$sLink.'graphiques"> GRAPHIQUES </a></li>
                	</ul>
                 </li>';
        						   }
    
        ?>		
    
        </ul>
    
        <?php } ?>
    
    								</nav>
    
    							
    							<!-- Footer -->
    								<footer id="footer">
    									<p class="copyright">&copy; Rémi Lefèvre & Gilles- Design inspiré de HTML5 UP.</p>
    								</footer>
    
    						</div>
    				</div>
    	
    		<!-- Scripts de gestion du menu-->
    			<script src="assets/js/jquery.min.js"></script>
    			<script src="assets/js/browser.min.js"></script>
    			<script src="assets/js/breakpoints.min.js"></script>
    			<script src="assets/js/util.js"></script>
    			<script src="assets/js/main.js"></script>
    
    
    
    	
    
    </section>	
    
    	</body>
    </html>

    le résultat donne ceci :

    Mon soucis c'est que j'aurais voulu obtenir :

    la première colonne comme actuellement date et heure,

    mais au lieu de la température de chaque ruche, celles-ci étant sur le même site (les légers écarts sont du à l'orientation et à la précision des capteurs) avoir comme le libellé de la 2eme colonne l'indique une moyenne (moyenne des températures des 5 ruches)par point horaire

    puis après mes colonnes avec uniquement le poids moyen horaire de chaque ruche.

    et non pas comme actuellement le poids ET la température de chaque ruche!

    C'est surement possible mais je ne vois pas trop comment modifier le code de la requête et l'affichage pour obtenir ce résultat!

    Voilà j'espère avoir été clair, sinon n'hésitez pas à me demander d'autres explications!

    Merci

    • Partager sur Facebook
    • Partager sur Twitter
      12 mai 2022 à 10:35:32

      Bonjour,

      GillesMangin-Voirin a écrit:

      au lieu de la température de chaque ruche, celles-ci étant sur le même site (les légers écarts sont du à l'orientation et à la précision des capteurs) avoir comme le libellé de la 2eme colonne l'indique une moyenne (moyenne des températures des 5 ruches)par point horaire

      Il y a sûrement plusieurs façons de voir les choses.

      Une idée serait d'utiliser une sous-requête qui calcule la moyenne par point horaire :

      SELECT
      	DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ) AS horodatage,
      	M.id_ruche,
      	MH.temperature,
      	ROUND(AVG(M.mas),2) AS poids
      FROM
      	Telemesures_ruches M
      		INNER JOIN (
      				-- Moyennes temperature
      				SELECT
      					DATE_FORMAT( horodatage, "%d-%m-%Y %H:00" ) AS point_horaire,
      					ROUND(AVG(tex),2) AS temperature
      				FROM Telemesures_ruches
      				WHERE horodatage >= NOW() - INTERVAL 50 DAY
      				GROUP BY DATE_FORMAT( horodatage, "%d-%m-%Y %H:00" )
      			) AS MH
      			ON DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ) = MH.point_horaire
      WHERE M.horodatage >= NOW() - INTERVAL 50 DAY
      GROUP BY
      	DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ),
      	M.id_ruche,
      	MH.horodatage
      ORDER BY
      	DATE_FORMAT( M.horodatage, "%Y-%m-%d %H:00" ) DESC,
      	M.id_ruche

      Dès lors, il faut modifier ta boucle PHP, ligne 143 à 182 dans ton code ci-dessus :

      	// On construit le tableau 2D
      	$donnees = array();
      	$moyennes = array();
      	foreach( $mesures as $mesure ) {
      		$moyennes[$mesure['horodatage']] = $mesure['temperature'];
      		$donnees[$mesure['horodatage']][$mesure['id_ruche']] = $mesure['poids'];
      	}
      	
      	// On boucle sur le 2D pour afficher les lignes
      	foreach ( $donnees as $date => $mesures ) {
      		$moyenne = $moyennes[$date];
      ?>
      								<tr>
      									<td><?= $date; ?></td>
      									<td><?= $moyenne; ?></td>
      <?php
      		foreach( $ruches as $ruche ) {
      ?>
      									<td>
      <?php
      		foreach( $mesures as $id => $valeur ) {
      			if( $id == $ruche['id_ruche'] ) echo $valeur['poids'];
      		}
      }
      ?>
      									</td>
      <?php
      		}
      ?>
      								</tr>
      <?php
      	}

      Bien évidemment à tester, je n'ai pas vérifier ...

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        12 mai 2022 à 16:46:24

        Salut je viens de tester vite fait la requête dans SQL :

        # 1054 - Champ 'MH.Horodatage' inconnu dans group statement.

        En enlevant le H de la ligne 22 cela tourne mais cela donne ceci :

        En tout cas ce niveau de création de requête est à des années lumières de ce que je suis capable de faire!

        Merci

        -
        Edité par GillesMangin-Voirin 12 mai 2022 à 16:46:54

        • Partager sur Facebook
        • Partager sur Twitter
          12 mai 2022 à 16:50:21

          Erreur de ma part (encore :) ) ...

          C'est MH.temperature dans le GROUP BY de la requête SQL.

          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
            12 mai 2022 à 18:47:44

            Bon je viens de tester effectivement la requête tourne nickel maintenant!

            Pour  l'affichage j'ai pas mal galéré il y avait dans mon code une accolade de fermeture en trop du coup plantage total assuré!

            par contre cette ligne :

            if( $id == $ruche['id_ruche'] ) echo $valeur['poids'];

            génère ceci:

            Warning: Illegal string offset 'poids' in /var/www/html/index.php on line 187

            5

            Du coup je l'ai remplacée par ceci :

            if( $id == $ruche['id_ruche'] ) echo $valeur;

            et cela semble fonctionner nickel :


            En déroulant plus le menu maintenant qu'il y a la température et des poids je me suis aperçu que comme le libellé des colonnes n'est plus visible on peut se demander à quoi correspondent les chiffres.

            Est -il possible de rajouter un °c après les chiffres des températures et un Kg après les valeurs de poids?

            Merci

            -
            Edité par GillesMangin-Voirin 12 mai 2022 à 18:56:01

            • Partager sur Facebook
            • Partager sur Twitter
              12 mai 2022 à 23:13:35

              Pour fixer les en-têtes de colonnes, il faut regarder côté CSS, avec des positions genre sticky ou fixed, passe par le forum HTML/CSS pour ces trucs là, mais le net doit déjà te retourner des réponses existantes.

              Pour rajouter °C et Kg, il te suffit de rajouter cela :

              echo $valeur.' °C'

              echo $moyenne.' Kg'

              • Partager sur Facebook
              • Partager sur Twitter
              Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                13 mai 2022 à 8:32:11

                Nickel,

                j'ai modifié ceci :

                Merci

                <?php
                
                
                    // On construit le tableau 2D
                    $donnees = array();
                    $moyennes = array();
                    foreach( $mesures as $mesure ) {
                        $moyennes[$mesure['horodatage']] = $mesure['temperature'];
                        $donnees[$mesure['horodatage']][$mesure['id_ruche']] = $mesure['poids'];
                    				   }
                     
                    // On boucle sur le 2D pour afficher les lignes
                
                    foreach ( $donnees as $date => $mesures ) {
                        					$moyenne = $moyennes[$date];
                ?>
                                                <tr>
                                                    <td><?= $date; ?></td>
                                                    <td><?= $moyenne.'°C'; ?></td>
                <?php 
                        foreach( $ruches as $ruche ) {
                ?>
                                                    <td>
                <?php
                
                            foreach( $mesures as $id => $valeur ) {
                                if( $id == $ruche['id_ruche'] ) echo $valeur.' Kg';
                            }
                
                				     } 
                ?>
                                                    </td>
                <?php
                        				      }	// fin de s'il y a des données 

                Pour la fixation des entêtes en css je vais attendre un peu car j'ai déjà une question sur le menu et ses problèmes (sans aucune réponse d'ailleurs)

                Merci

                • Partager sur Facebook
                • Partager sur Twitter

                Modification d'une requête pour rajout de données

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                • Editeur
                • Markdown