Soustraction dans requête mysql

Eléphanteau du PHP | 34 Messages

02 oct. 2012, 19:14

Bonjour à tous,

On va commencer par le commencement, j'ai une requête déjà existante dont le but est de récupérer les différentes interventions que je fais par correctif (panne). A l'heure actuelle j'affiche le temps total passé sur une intervention (en heure) et ça fonctionne... :)

Maintenant j'aimerai savoir quel est mon temps moyen passé sur toutes les interventions dans un mois. Pour cela j'ai besoin de faire une soustraction dans ma requête sql (enfin, je pense que c'est plus simple), le souci c'est que les 2 valeurs à soustraire sont déjà données par des opérations à l'intérieur de ma requête. Voila un exemple pour mieux comprendre parce que c'est pas facile à expliquer, à l'heure actuelle j'ai tenter ceci (qui ne fonctionne pas bien sur)
$correctif = mysql_query("SELECT date_appel, d.id, idCorrectif, intervention_id, SUM(TIMESTAMPDIFF(SECOND,debut_inter,fin_inter)) AS duree, SUM(TIME_TO_SEC(tps_acces_signature)) AS tps_acces, AVG(duree-tps_acces) AS moyenne
						FROM correctif AS c LEFT JOIN demande AS d ON c.id_appel = d.id LEFT JOIN work_times AS w ON intervention_id=$id_appel
						WHERE MONTH(date_appel)=$mois AND YEAR(date_appel)=$annee AND type_inter = 'Correctif'");
Je fais une soustraction de la date de début moins la date de fin d'intervention, le resultat est convertie en seconde et ajouter à duree
Ensuite je convertie le temps d’accès en seconde (C'est le temps que je perds à accéder à un logement et qui ne doit pas être compter dans mon temps passé sur l'intervention)

A partir de la je voudrais faire la soustraction de duree - tps_acces de chaque intervention et calculer la moyenne.

Le but étant de reconvertir le résultat en heure avec un code du style:
$dureeCorrectif = round($correctif['moyenne']/3600);}
Si quelqu'un sait comment je pourrais faire je suis preneur.

Merci d'avance

maxredphenix

Eléphant du PHP | 229 Messages

02 oct. 2012, 20:12

Bonjour,
J'ai pas lu le détail, mais pourquoi ne faire le calcul avec PHP par le bias de timestamps?

Eléphanteau du PHP | 34 Messages

02 oct. 2012, 20:30

Bonsoir,

Merci pour la réponse.

Je pensais pouvoir le faire directement via une requête en faisant le calcul direct sur les 2 valeurs.

Eléphant du PHP | 229 Messages

03 oct. 2012, 07:06

En sql tu fais
SELECT date1 - ddate2 as Nb_de jours_d_ecart FROM table
Il faudra surement utiliser la fonction intégrée to_date pour que le résultat soit correct et en minutes pour ton application.
Bonne journée

ViPHP
ViPHP | 2577 Messages

03 oct. 2012, 09:07

avg(TIMESTAMPDIFF(SECOND,debut_inter,fin_inter) - TIME_TO_SEC(tps_acces_signature)) ne marche pas ?

Eléphanteau du PHP | 34 Messages

03 oct. 2012, 22:05

Bonsoir,

Merci à vous 2. Ta solution fonctionne Mazarini, par contre je me rends compte que c'est pas le résultat de requête que j'attendais.

En effet pour tout expliquer (rapidement): pour chaque demande, je sélectionne le type d'intervention:correctif ou exploitation d'ou la table correctif dans la requête. Ensuite pour chaque type d'inter je peux créer une fiche d'intervention (table work_times), comme dit précédemment il y a autant de fiche que l'on souhaite par intervention (j'enregistre l'id de la table correctif/exploitation dans un champ de work_times).

Ma requête (qui fonctionne :D ) donne le temps total d'une seule intervention (via la correspondance entre l'id de la table work_times et celui de la table correctif ou exploitation) et la il me faudrait le mix de tous les totaux d'heures par type d'inter dans un mois donné....il faut donc que je trouve le moyen de lier ces 2 tables mais sans les id. Ca sent le noeud au cerveau.

Mais merci pour l'aide sur la formule parce que la je trouvais pas du tout comment faire.

Merci

Eléphant du PHP | 229 Messages

04 oct. 2012, 06:39

Sauf erreur de ma part, il ne manque plus que la fonction SUM().
SELECT SUM(avg(TIMESTAMPDIFF(SECOND,debut_inter,fin_inter) - TIME_TO_SEC(tps_acces_signature))) AS total_duree_inter;
SInon pour alléger le code, il faudrait créer une autre table (duree_inter)et un trigger qui a chaque nouveau tupple calcul la durée et enrichit la table nouvellement crée.

la table :
Image
Pour le trigger, je te laisse t'amuser.

Ensuit on fait un simple
SELECT SUM(duree) FROM duree_inter

Eléphanteau du PHP | 34 Messages

04 oct. 2012, 10:32

Exacte j'ai oublié le SUM. Je regarderai ce que ça donne ce soir en rentrant chez moi.

Je te tiens au courant.

Merci

Eléphanteau du PHP | 34 Messages

04 oct. 2012, 19:21

J'ai regardé, le plus logique est de mettre le SUM comme dans ma précédente requête. Par contre en faisant ça j'ai une erreur de mysql:
invalid use of group function:
SELECT date_appel, d.id, idCorrectif, intervention_id, AVG((SUM(TIMESTAMPDIFF(SECOND,debut_inter,fin_inter))) - (SUM(TIME_TO_SEC(tps_acces_signature)))) AS moyenne
	FROM correctif AS c LEFT JOIN demande AS d ON c.id_appel = d.id LEFT JOIN work_times AS w ON intervention_id=c.id_appel
	WHERE MONTH(date_appel)=6 AND YEAR(date_appel)=2012 AND type_inter = 'Correctif' AND statut='Cloturé'
Ca me le fait seulement lorsque je rajoute le SUM. Sinon j'ai un peu modifié la requête parce que c'est plus logique de calculer la moyenne sur le temps total passé sur une panne qui est fini, j'ai aussi modifié la correspondance entre les id des 2 tables concernées pour prendre en compte toutes les fiches de chaque inter d'un mois donné.

Je vois pas pourquoi on ne peut pas cumulé AVG et SUM c'est bizarre

Eléphant du PHP | 229 Messages

04 oct. 2012, 19:49

peut etre en faisant avg(sum()), plutot que sum(avg())
Sinon je ne sais pas.

Eléphanteau du PHP | 34 Messages

04 oct. 2012, 20:05

J'ai tenté ceci:
SELECT date_appel, d.id, idCorrectif, intervention_id, AVG(SUM((TIMESTAMPDIFF(SECOND,debut_inter,fin_inter)) - (TIME_TO_SEC(tps_acces_signature)))) AS moyenne
	FROM correctif AS c LEFT JOIN demande AS d ON c.id_appel = d.id LEFT JOIN work_times AS w ON intervention_id=c.id_appel
	WHERE MONTH(date_appel)=$mois AND YEAR(date_appel)=$annee  AND type_inter = 'Correctif' AND statut='Cloturé'
SELECT date_appel, d.id, idCorrectif, intervention_id, AVG((SUM(TIMESTAMPDIFF(SECOND,debut_inter,fin_inter))) - (SUM(TIME_TO_SEC(tps_acces_signature)))) AS moyenne
	FROM correctif AS c LEFT JOIN demande AS d ON c.id_appel = d.id LEFT JOIN work_times AS w ON intervention_id=c.id_appel
	WHERE MONTH(date_appel)=$mois AND YEAR(date_appel)=$annee AND type_inter = 'Correctif' AND statut='Cloturé'
J'ai beau chercher je vois pas, toujours la même erreur.

Eléphant du PHP | 229 Messages

04 oct. 2012, 20:45

Sans le avg()?

Ou en créant une fonction?

Eléphanteau du PHP | 34 Messages

04 oct. 2012, 20:59

Sans le AVG j'ai bien un résultat. Par rapport au données que j'ai rentré je devrais avoir 3 pannes:
1ere avec 6 heures d'intervention (4fiches)
2eme avec 1 heure (1 fiche)
3eme avec 3 heures (2 fiches)
soit .... 10 heures

Et sans le AVG je récupère 34200 dans la variable "moyenne", soit 34200/3600 : 9.5 heures. Après j'ai un round donc j'aurais bien mes 10 heures.

Mais du coup j'ai quand même un résultat potable, je vois pas pourquoi je peux pas rajouté ce fichu AVG pour avoir ma moyenne des 6, 1, 3 heures

Eléphant du PHP | 229 Messages

05 oct. 2012, 07:10

Voici la table pour mon exemple :

Image

Et la requête :
SELECT (
SUM( TIMESTAMPDIFF(
MINUTE , debut_inter, fin_inter ) ) + SUM( temps_acces )
) / COUNT( id ) AS total_inter
FROM test
A ajuster avec la clause WHERE, Puis une vue par type d'intervention plus une pour le globale comme dit ci dessous.
Modifié en dernier par schim59 le 05 oct. 2012, 08:39, modifié 3 fois.

ViPHP
ViPHP | 2577 Messages

05 oct. 2012, 08:20

Bonjour,

si j'ai bien compris, tu veux cumuler le temp d'intervention par demande et faire une moyenne des temps d'intervention par demande. Ca ne me semble pas possible en une seul requête.

Il faut créer une vue des temps d'intervention par demande et faire un moyenne sur la vue.