Bonjour à tous,

Depuis deux jours dejà je cherche et teste des codes pouvant me produire le résultat suivant, mais je me demande si finalement MySQL peut faire un tel miracle (car a chaque fois je m'en sors avec une valeur moyenne.. et c'est tout).

Production recherchée :
1
- Table

+-----------------------------+-----------------------------+
|       time                |       value               |
+-----------------------------+-----------------------------+
|       0.54829              |      47.2893                 |
|       0.82118              |      64.9254                 |
|       1.25785              |      3.82394                 |
|       1.48493              |      57.3573                 |
|       1.89425              |      356.289                 |
|       2.04567              |      146.381                 |
|       ...                 |       ...                         |
+-----------------------------+-----------------------------+

2 - Résultat de la requete

+-----------------------------+-----------------------------+
|       time                 |      value                   |
+-----------------------------+-----------------------------+
|       0.5                       |     47.2893                 |
|       1                          |     33.8563                 |
|       1.5                       |     57.3573                 |
|       ...                     |       ...                     |
+-----------------------------+-----------------------------+

Il s'agit donc de faire la moyenne des 'value' trouvées dans un intervalle donné de 'time'. Dans l'exemple l'intervalle est de 0.5, mais c'est en réalité une variable pouvant donc etre tout aussi égale à 1, 15.4 ou encore 3.82.

Pour le moment je récupère toutes les lignes et ensuite en php fait un traitement pour obtenir ce résultat mais ce n'est pas très optimal je trouve et souhaite donc savoir si une telle solution directement en sql existait (sans utiliser generate_series donc..)

Je vous remercie infiniement pour votre aide / lumière :)

4 réponses


Huggy
Réponse acceptée

Peut être en créant une fonction qui arrondi à 0.5 ...
voici un exemple pour arrondir les montants à 50 centimes près

delimiter |
CREATE FUNCTION arrondi50(v DECIMAL(8,2)) RETURNS DECIMAL(8,2)
    RETURN ROUND((v * 2) + 0.49999)/2; |
delimiter ;

en passant un second argument qui serait soit 0.5, 1 ou autre, et en adaptant le calcul, ça devrait le faire.

SELECT arrondi( time, 0.5) AS V,  AVG( value ) FROM matable GROUP BY  V
Canonier
Auteur

Merci pour ta rep (décidement t'es réactif ^^)

Le soucis c'est qu'au niveau de la requete la moyenne n'est pas limité au valeurs de time (meme apres passage par la fonction). Ce qui veut dire que j'ai un retour une seul ligne avec le premier time retourné et en value la moyenne de tous les lignes matchant les conditions dans le where (donc ici tout le tableau) :/

J'ai essayé aussi de passer par un left join :
D'abord je chope toutes les intervalles et ensuite je lie la moyenne des lignes dont l'equart est inf ou egale à l'equart recherché divisé par deux.

....c'est pas clair x)

Un truc du genre : LEFT JOIN table ON ABS(a.time - b.time) * 2 <= equart

Mais idem c'était pas beau..
Du coup je pense que le soucis c'est l'application de la fonction AVG.. T'en penses quoi ?

EDIT :
Le sujet n'est pas validé hein.. fausse manip :/

boulet

chez moi ça donne ça :
T AVG (value)
1.00 56.10735
1.50 30.59062
2.00 356.289
2.50 146.381
avec la requête suivante

SELECT arrondi50(time) AS T , AVG (value) FROM mesures GROUP BY T

ça fait bien la moyenne uniquement sur les "time" de même arrondi
bon OK mon calcul n'est pas celui que tu voudrais (le 0.548829 est arrondi à 1) mais c'est un exemple

Canonier
Auteur

Autant pour moi, j'ai mal recopier la fonction de base ><