Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème SQL AVG(x)

Sujet résolu
    30 septembre 2010 à 7:35:25

    Bonjour,

    J'ai un formulaire dans lequel je peux insérer une variable x et une variable y. Lorsque je clique sur envoyer, elle s'insère dans une table SQL. Problème : je veux insérer dans ma table les variables centrées c'est à dire "x - la moyenne de x" et "y - la moyenne de y".
    A chaque fois que SQL calcul la moyenne de x il ne prend pas en compte la dernière variable x insérer dans la table de même pour la variable y.

    Merci d'avance pour votre aide.

    <form method="post" action="regression.php">
    <label for="x">variable x</label>
    <input tabindex="10" type="text" name="x" id="x" value="" size="10" maxlength="10" />
    <label for="y">Variable y</label>
    <input tabindex="20" type="text" name="y" id="y" value="" size="10" maxlength="10" />
    <input type="submit" value="Envoyer" /><input type="reset" />
    </form>
    <?php



    if (isset($_POST['x']) AND (isset($_POST['y'])))
    {
    try
    {
    $bdd = new PDO('mysql:host=localhost;dbname=test', 'root', '');
    }
    catch(Exception $e)
    {
    die('Erreur : '.$e->getMessage());
    }
    //variable x
    $x = $_POST['x'];
    //variable y
    $y = $_POST['y'];

    //variable centrée x
    $reponsea = $bdd->query('SELECT AVG(x) AS avg_x FROM regression');
    $donneesa = $reponsea->fetch();
    $Xcentre = $x - $donneesa['avg_x'];

    //variable centrée y
    $reponseb = $bdd->query('SELECT AVG(y) AS avg_y FROM regression');
    $donneesb = $reponseb->fetch();
    $Ycentre = $y - $donneesb['avg_y'];

    $req = $bdd->prepare('INSERT INTO regression(x, y, Xcentre, Ycentre) VALUES(:x, :y, :Xcentre, :Ycentre)');
    $req->execute(array(
    'x' => $x = htmlspecialchars($_POST['x']),
    'y' => $y = htmlspecialchars($_POST['y']),
    'Xcentre' => $Xcentre,
    'Ycentre' => $Ycentre,
    ));

    }
    ?>
    <table border="1">
    <tr>
    <td>Table</td>
    <td>x </td>
    <td>y</td>
    <td>Xcentre</td>
    <td>Ycentre</td>
    </tr>

    <?php
    try
    {
    $bdd = new PDO('mysql:host=localhost;dbname=test', 'root', '');
    }
    catch(Exception $e)
    {
    die('Erreur : '.$e->getMessage());
    }

    $reponse = $bdd->query('SELECT x, y, Xcentre, Ycentre FROM regression');
    while ($donnees = $reponse->fetch())

    echo '<tr> <td></td>
    <td>' .$donnees['x']. '</td><td>' .$donnees['y']. '</td>
    <td>' .$donnees['Xcentre']. '</td><td>' .$donnees['Ycentre']. '</td>
    </tr>';
    ?>
    </tr>
    <tr>
    <td>moyenne</td>
    <td><?php
    $reponse1 = $bdd->query('SELECT AVG(x) AS avg_x FROM regression');
    $donnees1 = $reponse1->fetch();
    echo '' .$donnees1['avg_x']. '</td>';
    ?>
    </td>
    <td><?php
    $reponse2 = $bdd->query('SELECT AVG(y) AS avg_y FROM regression');
    $donnees2 = $reponse2->fetch();
    echo '' .$donnees2['avg_y']. '</td>';
    ?>
    </td>
    </tr>
    </table>
    • Partager sur Facebook
    • Partager sur Twitter
      30 septembre 2010 à 7:46:05

      Salut,
      T'as un clavier qwerty toi, non?

      Est-ce que tu pourrais nous montrer ta requête?
      Là comme ça je suppose que dans ton insert tu mets directement AVG(x). Ta dernière valeur n'ayant pas encore été inséré dans la table, c'est normal qu'il ne la prenne pas en compte.
      Tu devrais pouvoir le remplacer par quelque chose comme :
      (SUM(x)+x)/(COUNT(x)+1)

      Edit: grillé par l'edit, la requète et le code ont été rajouté
      • Partager sur Facebook
      • Partager sur Twitter
        30 septembre 2010 à 10:17:12

        Un grand merci Belsion,

        J'avais effectivement pensé à faire un SUM et un COUNT mais je n'avais pas pensé à faire un "+ x" et "+ 1"...

        A+
        • Partager sur Facebook
        • Partager sur Twitter
          3 octobre 2010 à 7:09:02

          Bonjour,

          Maintenant le problème est au niveau des variables centrées. Certes, le calcul est bon (grâce à Belsion)mais les variables centrées précédentes n'affichent plus le bon réultat étant donné qu'à chaque fois que l'on insère une nouvelle variable x et y les valeurs des variables centrées devraient changer à leur tour puisque la moyenne change.

          J'avoue que là je suis un peu perdu...Merci pour votre aide

          • Partager sur Facebook
          • Partager sur Twitter
            3 octobre 2010 à 11:24:14

            Si tu ne voulais pas stocker une valeur différente des moyennes pour chaque ligne, pourquoi as-tu stocké une valeur dans chaque ligne ? Ça n'a aucun sens.

            Mets tes moyennes dans une autre table, ou recalcule-les à la demande.
            • Partager sur Facebook
            • Partager sur Twitter
              5 octobre 2010 à 10:26:37

              Re bonjour!

              Oui en effet ça n'a pas de sens si je stock une valeur alors qu'elle est supposée de changer à chaque fois que j'insère une variable x et une variable y dans le formulaire. j'ai donc changer mon script ainsi :
              <form method="post" action="reg_forum.php">
              	<label for="x">variable x</label>
              	<input tabindex="10" type="text" name="x" id="x" value="" size="10" maxlength="10" />
              	<label for="y">Variable y</label>
              	<input tabindex="20" type="text" name="y" id="y" value="" size="10" maxlength="10" />
              	<input type="submit" value="Envoyer" /><input type="reset" />
              	</form>
              
              
              <!--///////////////////////////////////////////////////////////////////////////////////////////-->
              
              
              <?php
              
              if (isset($_POST['x']) AND (isset($_POST['y'])))
              {
              try
              {
              		$bdd = new PDO('mysql:host=localhost;dbname=test', 'root', 'bolivia3');
              }
              catch(Exception $e)
              {
              	    die('Erreur : '.$e->getMessage());
              }
              // variable n
              $reponse0 = $bdd->query('SELECT COUNT(n) AS nbre_n FROM regression'); 
              $donnees0 = $reponse0->fetch();
              $n1 = $donnees0['nbre_n'];
              				
              for ($n = 1; $n <= $n1; $n++);
              //variable x
              $x = $_POST['x'];
              //variable y
              $y = $_POST['y'];
              
              $req = $bdd->prepare('INSERT INTO regression(n, x, y) VALUES(:n, :x, :y)');
              $req->execute(array(
              'n' => $n,
              'x' => $x = htmlspecialchars($_POST['x']),
              'y' => $y = htmlspecialchars($_POST['y']),
              ));
              }
              ?>
              
              <table border="1" width="100%">
              		<tr>
              			<td>Table</td> 
              			<td>n</td> 
              			<td>x</td>   
              			<td>y</td>    
              			<td>X=x-(moy de x)</td>   
              			<td>Y=y-(moy de y)</td>
              		</tr>
              
              		
              		<?php
              		try
              		{
              			$bdd = new PDO('mysql:host=localhost;dbname=test', 'root', '');
              		}
              			catch(Exception $e)
              		{
              			die('Erreur : '.$e->getMessage());
              		}
              			$reponse = $bdd->query('SELECT n, x, y FROM regression');
              
              		while ($donnees = $reponse->fetch())
              		{
              			echo '	
              		
              		<tr>	<td></td>
              				<td>' .$donnees['n']. '</td>
              				<td>' .$donnees['x']. '</td>
              				<td>' .$donnees['y']. '</td>
              				<td>'; 	$reponseb = $bdd->query('SELECT SUM(x) AS sum_x FROM regression');
              						$donneesb = $reponseb->fetch();
              						$reponsec = $bdd->query('SELECT COUNT(x) AS count_x FROM regression');
              						$donneesc = $reponsec->fetch();
              						$Xcentre = $donnees['x'] - (($donneesb['sum_x']) / ($donneesc['count_x'])); 
              						echo $Xcentre.'</td>
              				<td>'; 	$reponsed = $bdd->query('SELECT SUM(y) AS sum_y FROM regression');
              						$donneesd = $reponsed->fetch();
              						$Ycentre = $donnees['y'] - (($donneesd['sum_y']) / ($donneesc['count_x'])); 
              						echo $Ycentre.'</td>
              		</tr>';
              		}
              		?>
              		<tr>
              				<td>moyenne</td>
              				<td><?php 
              					$reponse0 = $bdd->query('SELECT AVG(n) AS avg_n FROM regression');
              					$donnees0 = $reponse0->fetch();
              					echo '' .$donnees0['avg_n']. '</td>';
              					?></td>
              				<td><?php
              					$reponse1 = $bdd->query('SELECT AVG(x) AS avg_x FROM regression');
              					$donnees1 = $reponse1->fetch();
              					echo '' .$donnees1['avg_x']. '</td>';
              					?>
              				</td>
              				<td><?php
              					$reponse2 = $bdd->query('SELECT AVG(y) AS avg_y FROM regression');
              					$donnees2 = $reponse2->fetch();
              					echo '' .$donnees2['avg_y']. '</td>';
              					?>
              				</td>
              		</tr>
              		<tr>
              			<td>TOTAL</td>
              			<td><?php
              					$reponse50 = $bdd->query('SELECT SUM(n) AS sum_n FROM regression');
              					while ($donnees50 = $reponse50->fetch())
              					echo '' .$donnees50['sum_n']. '</td>';
              				?></td>
              			<td><?php
              					$reponse5 = $bdd->query('SELECT SUM(x) AS sum_x FROM regression');
              					while ($donnees5 = $reponse5->fetch())
              					echo '' .$donnees5['sum_x']. '</td>';
              				?></td>
              			<td><?php
              					$reponse6 = $bdd->query('SELECT SUM(y) AS sum_y FROM regression');
              					while ($donnees6 = $reponse6->fetch())
              					echo '' .$donnees6['sum_y']. '</td>';
              				?>
              			</td>
              		</tr>
              </table>
              	<form method="post" action="reg_update_forum.php">
              	<input type="submit" value="UPDATE" />
              	</form>	
              </body>
              
              </html>
              


              Cependant j'aimerai bien calculer la moyenne et le total des variables centrées X et Y. Et pour cela il me semble que le moyen le plus simple serait donc d'insérer ces variables dans une table et ensuite grâce à SQL faire un (AVG_X). J'ai donc décidé de mettre en bas de mon tableau un bouton "UPDATE" dont le script se situe dans un autre fichier mais qui renvoie au formulaire suite à son éxécution. Voici son script:

              <?php
              try
              		{
              			$bdd = new PDO('mysql:host=localhost;dbname=test', 'root', '');
              		}
              			catch(Exception $e)
              		{
              			die('Erreur : '.$e->getMessage());
              		}
              
              		$reponse = $bdd->query('SELECT n, x, y FROM regression');
              
              		while ($donnees = $reponse->fetch())
              		{
              		
              //X
              $reponseb = $bdd->query('SELECT SUM(x) AS sum_x FROM regression');
              $donneesb = $reponseb->fetch();
              $reponsec = $bdd->query('SELECT COUNT(x) AS count_x FROM regression');
              $donneesc = $reponsec->fetch();
              $Xcentre = $donnees['x'] - (($donneesb['sum_x']) / ($donneesc['count_x'])); 
              //Y
              $reponsed = $bdd->query('SELECT SUM(y) AS sum_y FROM regression');
              $donneesd = $reponsed->fetch();
              $Ycentre = $donnees['y'] - (($donneesd['sum_y']) / ($donneesc['count_x'])); 
               
              }
              
              
              		$repa = $bdd->prepare('UPDATE regression SET Xcentre = :Xcentre, Ycentre = :Ycentre');
              		$repa->execute(array(
              			'Xcentre'=>$Xcentre,
              			'Ycentre'=>$Ycentre,
              			));
              	
              header('Location: reg_forum.php');
              		
              ?>
              

              Le problème est qu'il n'insère dans la table que le calcul de la dernière ligne et non le calcul de chaque ligne. Ainsi le résultat de la dernière ligne sera insérer dans toutes les entrées du champ Xcentre et du champ Ycentre.

              Comment je peux dire à SQL qu'il prenne en compte le calcul de chaque ligne? Ou sinon comment dois-je m'y prendre?

              Merci pour votre aide
              • Partager sur Facebook
              • Partager sur Twitter
                5 octobre 2010 à 11:55:09

                Euargl.

                Utilise les balises <code type="php">, ce sera plus lisible...
                • Partager sur Facebook
                • Partager sur Twitter
                  5 octobre 2010 à 20:46:39

                  Mets ton UPDATE dans ta boucle while ?
                  • Partager sur Facebook
                  • Partager sur Twitter
                    6 octobre 2010 à 18:24:02

                    J'ai essayé en faisant ceci mais ça ne marche pas...

                    <?php
                    try
                    {
                    $bdd = new PDO('mysql:host=localhost;dbname=test', 'root', '');
                    }
                    catch(Exception $e)
                    {
                    die('Erreur : '.$e->getMessage());
                    }
                    
                    $reponse = $bdd->query('SELECT n, x, y FROM regression');
                    
                    while ($donnees = $reponse->fetch())
                    {
                    		
                    //X
                    $reponseb = $bdd->query('SELECT SUM(x) AS sum_x FROM regression');
                    $donneesb = $reponseb->fetch();
                    $reponsec = $bdd->query('SELECT COUNT(x) AS count_x FROM regression');
                    $donneesc = $reponsec->fetch();
                    $Xcentre = $donnees['x'] - (($donneesb['sum_x']) / ($donneesc['count_x'])); 
                    //Y
                    $reponsed = $bdd->query('SELECT SUM(y) AS sum_y FROM regression');
                    $donneesd = $reponsed->fetch();
                    $Ycentre = $donnees['y'] - (($donneesd['sum_y']) / ($donneesc['count_x'])); 
                     
                    $repa = $bdd->prepare('UPDATE regression SET Xcentre = :Xcentre, Ycentre = :Ycentre');
                    		$repa->execute(array(
                    			'Xcentre'=>$Xcentre,
                    			'Ycentre'=>$Ycentre,
                    			));
                    }	
                    header('Location: reg_forum.php');
                    		
                    ?>
                    
                    • Partager sur Facebook
                    • Partager sur Twitter
                      6 octobre 2010 à 22:39:08

                      Réponse pour le post un peu plus haut (celui avec 2 codes) :

                      'x' => $x = htmlspecialchars($_POST['x']),
                      'y' => $y = htmlspecialchars($_POST['y']),
                      


                      Pitié...

                      Sinon :

                      Tu recalcules la moyenne (avec du SQL) à chaque itération de la boucle... tu n'as besoin de le faire qu'une seule fois, au début.

                      Dans le second code, tu mets aussi dans ta boucle des requêtes qui font à chaque itération la même chose, donc inutile.

                      Même erreur dans le code du dernier post.

                      Si tu tiens à stocker les moyennes dans chaque ligne de la table (il n'y a aucune raison de le faire, vu que les données sont identiques pour toutes les lignes, mais enfin si tu y tiens), il suffit de mettre :

                      UPDATE regression SET
                      Xcentre = (SELECT avg(x) FROM regression),
                      Ycentre = (SELECT avg(x) FROM regression)
                      


                      Même idée, mais pourquoi afficher la même moyenne à chaque ligne ? Il suffit de l'afficher une fois dans le tableau...
                      • Partager sur Facebook
                      • Partager sur Twitter
                        7 octobre 2010 à 15:05:29

                        Salut

                        Au fait, je veux calculer les variables centrées. Il s'agit de x moins la moyenne de x. A chaque fois que l'on insère un x il est normal que sa moyenne change et par conséquent les variables centrées aussi.
                        J'ai essayé de faire ce que tu m'as dit mais ça me donne toujours le même résultat à savoir: il insère dans la table sur toutes les lignes le résultat de la première ligne :

                        $reponsee = $bdd->query('SELECT (x - avg(x)) AS Xcentre FROM regression');
                        while ($donneese = $reponsee->fetch())
                        {
                        $Xcentre1 = $donneese['Xcentre'];
                        
                        $repa = $bdd->prepare('UPDATE regression SET Xcentre = :Xcentre');
                        $repa->execute(array(
                        'Xcentre'=> $Xcentre1,
                        ));
                        }
                        


                        J'ai également essayé ainsi mais cette fois-ci il insère 0 dans toutes les lignes :

                        $repa = $bdd->exec('UPDATE regression SET Xcentre = (SELECT (x - avg(x)) FROM regression)');
                        
                        • Partager sur Facebook
                        • Partager sur Twitter
                          7 octobre 2010 à 15:18:09

                          Ah OK, je viens de comprendre.

                          mysql> DROP TABLE test;
                          Query OK, 0 rows affected (0.00 sec)
                          
                          mysql> CREATE TABLE test( x FLOAT );
                          Query OK, 0 rows affected (0.10 sec)
                          
                          mysql> INSERT INTO test (x) VALUES (1),(2),(3),(4);
                          Query OK, 4 rows affected (0.00 sec)
                          Records: 4  Duplicates: 0  Warnings: 0
                          
                          mysql> SELECT x, x - (SELECT avg(x) FROM test) AS xcentre FROM test;
                          +------+---------+
                          | x    | xcentre |
                          +------+---------+
                          |    1 |    -1.5 |
                          |    2 |    -0.5 |
                          |    3 |     0.5 |
                          |    4 |     1.5 |
                          +------+---------+
                          4 rows in set (0.00 sec)
                          
                          mysql> CREATE VIEW testc AS SELECT x, x - (SELECT avg(x) FROM test) AS xcentre FROM test;
                          Query OK, 0 rows affected (0.10 sec)
                          
                          mysql> SELECT * FROM testc;
                          +------+---------+
                          | x    | xcentre |
                          +------+---------+
                          |    1 |    -1.5 |
                          |    2 |    -0.5 |
                          |    3 |     0.5 |
                          |    4 |     1.5 |
                          +------+---------+
                          4 rows in set (0.01 sec)
                          


                          Si tu veux stocker les valeurs centrées :

                          mysql> ALTER TABLE test ADD xc FLOAT;
                          Query OK, 4 rows affected (0.11 sec)
                          Records: 4  Duplicates: 0  Warnings: 0
                          
                          -- LOL, MySQL :
                          
                          mysql> UPDATE test SET xc = x - (SELECT avg(x) FROM test);
                          ERROR 1093 (HY000): You can't specify target table 'test' for update in FROM clause
                          
                          mysql> UPDATE test SET xc = x - (SELECT * FROM (SELECT avg(x) FROM test LIMIT 1) AS foo);
                          Query OK, 4 rows affected (0.00 sec)
                          Rows matched: 4  Changed: 4  Warnings: 0
                          
                          mysql> SELECT * FROM test;
                          +------+------+
                          | x    | xc   |
                          +------+------+
                          |    1 | -1.5 |
                          |    2 | -0.5 |
                          |    3 |  0.5 |
                          |    4 |  1.5 |
                          +------+------+
                          4 rows in set (0.00 sec)
                          
                          • Partager sur Facebook
                          • Partager sur Twitter
                            7 octobre 2010 à 18:47:15

                            WOW o_O

                            Ca marche!!!

                            UN GRAND MERCI Lord Casque Noir! Et en plus j'ai appris de nouvelles choses avec sql...



                            $sql = $bdd->query('SELECT x, x - (SELECT avg(x) FROM regression) AS xcentre FROM regression');
                            
                            $sql2 = $bdd->query('UPDATE regression SET Xcentre = x - (SELECT * FROM (SELECT avg(x) FROM regression LIMIT 1) AS foo)');
                            
                            $sql3 = $bdd->query('SELECT y, y - (SELECT avg(y) FROM regression) AS ycentre FROM regression');
                            
                            $sql4 = $bdd->query('UPDATE regression SET Ycentre = y - (SELECT * FROM (SELECT avg(y) FROM regression LIMIT 1) AS foo)');
                            
                            • Partager sur Facebook
                            • Partager sur Twitter
                              7 octobre 2010 à 19:33:23

                              De rien ;)
                              Tu peux faire les 2 UPDATE dans la même requête, au fait.
                              • Partager sur Facebook
                              • Partager sur Twitter

                              Problème SQL AVG(x)

                              × 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