IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Requête calcul moyenne sans les valeurs NULL [MySQL]


Sujet :

PHP & Base de données

  1. #21
    Membre averti
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2023
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 19
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Octobre 2023
    Messages : 37
    Par défaut
    Citation Envoyé par Séb. Voir le message
    Non, tu manipules des numériques il faut donc un type SQL DECIMAL (ou INTEGER si tu as seulement des entiers), le VARCHAR sert uniquement pour du texte.
    Les difficultés autour de cela viennent d'une méconnaissance et pas du type de données utilisé.


    Insérer les données correctement. Quand la valeur est absente tu utilises le marqueur SQL NULL => La fonction SQL NULLIF() sera utile

    NULLIF(param1, param2) -- Renvoie NULL si param1 est égal à param2, sinon renvoie param1

    https://dev.mysql.com/doc/refman/8.0...unction_nullif

    Le script PHP est une vraie horreur.

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    function insertReading($sensor, $location, $value1, $value2, $value3, $value4, $pm25, $pm10) {
        global $servername, $username, $password, $dbname;
     
        // Create connection
        $conn = new mysqli($servername, $username, $password, $dbname);
        // Check connection
        if ($conn->connect_error) {
          die("Connection failed: " . $conn->connect_error);
        }
     
        $sql = "INSERT INTO SensorData (sensor, location, value1, value2, value3, value4, pm25, pm10)
     
           VALUES ('" . $sensor . "', '" . $location . "', '" . $value1 . "', '" . $value2 . "', '" . $value3 . "','" . $value4 . "', '" . $pm25 . "', '" . $pm10 ."')";
     
       if ($conn->query($sql) === TRUE) {
          return "New record created successfully";
     
        }
    }

    En le remaniant un minimum :

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    function insertReading($sensor, $location, $value1, $value2, $value3, $value4, $pm25, $pm10)
    {
        global $servername, $username, $password, $dbname;
     
        // La connexion devrait être un paramètre de la fonction
        $conn = new mysqli($servername, $username, $password, $dbname);
        if ($conn->connect_error) {
          die("Connection failed: " . $conn->connect_error);
        }
     
        $sensor = $conn->real_escape_string($sensor);
        $location = $conn->real_escape_string($location);
        $value1 = $conn->real_escape_string($value1);
        $value2 = $conn->real_escape_string($value2);
        $value3 = $conn->real_escape_string($value3);
        $value4 = $conn->real_escape_string($value4);
        $pm25 = $conn->real_escape_string($pm25);
        $pm10 = $conn->real_escape_string($pm10);
     
        // Syntaxe INSERT/SET, propriétaire MySQL mais tellement plus lisible...
        // Je te mets du NULL partout si chaîne de valeur vide, à adapter
        $sql = <<<SQL
            INSERT INTO SensorData
            SET
                sensor = '{$sensor}',
                location '{$location}',
                value1 = NULLIF('{$value1}, ''),
                value2 = NULLIF('{$value2}, ''),
                value3 = NULLIF('{$value3}, ''),
                value4 = NuLLIF('{$value4}, ''),
                pm25 = NULLIF('{$pm25}', ''),
                pm10 = NULLIF('{$pm10}', '')
             SQL;
     
        if ($conn->query($sql) !== TRUE) {
            return "INSERT failed";
        }
     
        return "New record created successfully";
    }
    Bonjour,
    J'ai saisi les quelques lignes de code que tu as proposé mais j'ai l'erreur suivante :

    Parse error: Invalid body indentation level (expecting an indentation level of at least 10) in /storage/ssd4/987/21478987/public_html/esp-database.php on line 47


    La ligne 47 correspondant à : INSERT INTO SensorData je pense qu'il y a une erreur de syntaxe avec la ligne précédente j'ai essayé de trouver un exemple similaire pour corriger mais sans succés.

  2. #22
    Membre chevronné
    Homme Profil pro
    Urbaniste
    Inscrit en
    Août 2023
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Urbaniste

    Informations forums :
    Inscription : Août 2023
    Messages : 387
    Par défaut
    Bonjour,

    c'est la syntaxe HEREDOC qui est malformée.

    https://www.php.net/manual/fr/langua...syntax.heredoc

    Il faudrait, au choix, décaler la requête vers la droite,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        $sql = <<<SQL
    		INSERT INTO SensorData
    		SET
    		    sensor = '{$sensor}',
    		    location '{$location}',
    		    value1 = NULLIF('{$value1}, ''),
    		    value2 = NULLIF('{$value2}, ''),
    		    value3 = NULLIF('{$value3}, ''),
    		    value4 = NuLLIF('{$value4}, ''),
    		    pm25 = NULLIF('{$pm25}', ''),
    		    pm10 = NULLIF('{$pm10}', '')
             SQL;
    Ou, décaler les identifiants HEREDOC vers la gauche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $sql = <<<SQL
    	INSERT INTO SensorData
    	SET
    		sensor = '{$sensor}',
    		location '{$location}',
    		value1 = NULLIF('{$value1}, ''),
    		value2 = NULLIF('{$value2}, ''),
    		value3 = NULLIF('{$value3}, ''),
    		value4 = NuLLIF('{$value4}, ''),
    		pm25 = NULLIF('{$pm25}', ''),
    		pm10 = NULLIF('{$pm10}', '')
    SQL;
    Il me semble qu'on peut tout aussi bien écrire ceci avec des guillemets double, à vérifier.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $toto = "INSERT INTO SensorData
    	SET
    		sensor = '{$sensor}',
    		location '{$location}',
    		value1 = NULLIF('{$value1}, ''),
    		value2 = NULLIF('{$value2}, ''),
    		value3 = NULLIF('{$value3}, ''),
    		value4 = NuLLIF('{$value4}, ''),
    		pm25 = NULLIF('{$pm25}', ''),
    		pm10 = NULLIF('{$pm10}', '')";
    Bonne journée.

  3. #23
    Expert confirmé
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 351
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 351
    Billets dans le blog
    17
    Par défaut
    En effet, mauvaise indentation du terminateur (1 espace de trop).

    Je corrige :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
        // Syntaxe INSERT/SET, propriétaire MySQL mais tellement plus lisible...
        // Je te mets du NULL partout si chaîne de valeur vide, à adapter
        $sql = <<<SQL
            INSERT INTO SensorData
            SET
                sensor = '{$sensor}',
                location '{$location}',
                value1 = NULLIF('{$value1}, ''),
                value2 = NULLIF('{$value2}, ''),
                value3 = NULLIF('{$value3}, ''),
                value4 = NuLLIF('{$value4}, ''),
                pm25 = NULLIF('{$pm25}', ''),
                pm10 = NULLIF('{$pm10}', '')
            SQL;

  4. #24
    Membre averti
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2023
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 19
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Octobre 2023
    Messages : 37
    Par défaut
    Bon j'ai bien avancé.
    J'ai standardisé ma BDD avec désormais uniquement des données en DECIMAL j'ai effectué les modifications pour insérer les valeurs comme proposé précédemment et ça fonctionne,


    Vous m'aviez proposé cette ligne lors de l'insertion des données dans la BDD, est ce encore utile ? :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $pm10 = $conn->real_escape_string($pm10);
    Je vais ce genre de requête pour le calcul des moyennes Auparavant avec mon bazar de valeurs en varchar j'avais contourné le pb avec cela : et je me demande si cela est encore utile le CAST

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $sql = "SELECT AVG(CAST(" . $value . " AS SIGNED)) AS avg_amount FROM SensorData WHERE reading_time BETWEEN NOW() - INTERVAL ". $nbdays ." DAY AND NOW()";
    Je vais encore continuer à bosser mais un grand merci.

  5. #25
    Membre chevronné
    Homme Profil pro
    Urbaniste
    Inscrit en
    Août 2023
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Urbaniste

    Informations forums :
    Inscription : Août 2023
    Messages : 387
    Par défaut
    Bonjour,

    à mon avis plutôt que d'utiliser mysqli_real_escape_string et la concaténation de string,
    comme dans ("SELECT AVG(CAST(" . $value . " AS SIGNED))..."),
    vous devriez vous coller à utiliser des requêtes préparées avec des paramètres nommés.

    https://www.php.net/manual/fr/mysqli...statements.php

    mysqli_real_escape_string nécessite un tout petit peu de paramétrage dont je suis à peu près certain
    que l'on ne peut pas s'appuyer dessus de manière sereine.
    https://www.php.net/manual/fr/mysqli...ape-string.php

    Bonne journée.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Faire un paréto sans les valeurs nulles
    Par salseropom dans le forum Excel
    Réponses: 3
    Dernier message: 14/04/2020, 14h16
  2. Réponses: 8
    Dernier message: 05/08/2016, 11h27
  3. Faire une moyenne en ignorant les valeurs nulles
    Par Giansolo dans le forum MATLAB
    Réponses: 2
    Dernier message: 08/06/2007, 14h38
  4. order by sans les valeurs NULL
    Par pendragon509 dans le forum Langage SQL
    Réponses: 4
    Dernier message: 21/10/2005, 12h31
  5. Comment gérer les valeur Nulles dans une requête ?
    Par sondo dans le forum Bases de données
    Réponses: 3
    Dernier message: 16/03/2005, 11h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo