8800 sujets

Développement web côté serveur, CMS

Pages :
Tout d'abord, bonjour à toutes et à tous.

Je fais face à un problème que je n'arrive pas à résoudre et je me suis dit que peut-être quelqu'un sur ce forum pourrait me donner des pistes pour le résoudre.

Voilà je possède une table Mysql nommée "consommation" où se situe 3 champs différents :

- Valeur (valeur de la consommation)
- Date (date où la consommation a été enregistrée au format YY:MM:DD HH:MM:SS)
- Type (type de la consommation).

Je souhaiterai pouvoir récupérer la dernière valeur instantanée de la consommation (la table se remplie toute les 10 min) et la comparer avec la valeur de la consommation de l'heure précédente.

Pour simplifier la chose, je souhaite comparer data(t) avec data(t - 1h).

Mon problème se situe au moment de la récupération de data(t-1).

Par exemple, si l'heure à laquelle je réalise cette requête se trouve être 00:30:00 je dois changer de jour pour prendre la valeur de la veille à 23:30:00.

Le problème se corse si le jour où je réalise cette requête se trouve être le 1er janvier => Problème pour récupérer la valeur du 31 Août à 23:30:00 de l'année précédente.


De plus, j'ai commencé à insérer des valeurs dans ma base qu'à partir du premier janvier et je ne vois pas comment faire pour palier au problème des données non existante avant cette date.



Voilà j'espère que le problème que je viens d'exposer est bien clair, et que quelqu'un pourra m'aider dans cette prise de tête.

En tout cas merci d'avance! Smiley smile
Modifié par lorenzo_one (01 Sep 2011 - 11:29)
Merci de ta réponse si rapide.

Voici le script que j'utilise :


$query = 	"SELECT val_conso FROM $table WHERE $time AND HOUR(date_conso) = HOUR(NOW())
ORDER BY date_conso DESC"	//sélectionne la dernière valeur de la période souhaitée
or die('Impossible d\'exécuter la requête :' . mysql_error());		//Sinon ce message d'erreur s'affiche		
		
$result = mysql_query($query); // on place le résultat de la requête dans une variable result
			
$data = mysql_fetch_array($result);	//on récupère le résultat dans un tableau nommé data
			
$resultat = array('data' => $data['val_conso']); //$data['val'] est un array et je l'insère dans un array multidimensionnel (ça permet par exemple d'avoir autre chose que "data" dans ce tableau)  
			 
			
$query = 	"SELECT val_conso  FROM $table WHERE $time AND HOUR(date_conso) = HOUR(NOW() - INTERVAL 1 HOUR) 
ORDER BY date_conso DESC"	//sélectionne la dernière valeur de la période souhaitée
						or die('Impossible d\'exécuter la requête :' . mysql_error());		//Sinon ce message d'erreur s'affiche
			
$result = mysql_query($query); // on place le résultat de la requête dans une variable result
						
$data = mysql_fetch_array($result);	//on récupère le résultat dans un tableau nommé data
			
$resultat += array('data_1h' => $data['val_conso']);

Modifié par lorenzo_one (31 Aug 2011 - 15:36)
Modérateur
Tu devrais plutôt essayer avec la fonction DATE_ADD que j'ai mentionné. Elle gère bien le changement d'heure d'une journée à l'autre. Il faudra évidemment adapter un peu tes requêtes SQL.
Merci Tony Monast, en lisant ta remarque je me suis aperçu que ma requête n'était pas judicieuse et pour éviter de changer tout mon code, j'ai essayer d'utiliser la requête suivante :

$query ="SELECT val_conso FROM $table WHERE DATE(date_conso) = DATE('2011-02-02 00:00:00' -INTERVAL 1 MONTH)
ORDER BY date_conso DESC"	//sélectionne la dernière valeur de la période souhaitée
or die('Impossible d\'exécuter la requête :' . mysql_error());		//Sinon ce message d'erreur s'affiche


Et du coup maintenant cela fonctionne bien et résoud donc la prmière partie de mon problème.

Je te remercie vraiment beaucoup!

Sinon aurais-tu une idée pour le problème des données non existante avant le 1er janvier ( car du coup il m'est impossible de faire des comparaisons et la requête me renvoie une valeur NULL
Ok merci pour cette fonction que je connaissais pas! ça devrait résoudre mon problème.

Vraiment encore merci pour ta disponibilité et ta rapidité d'action. J'aurai du venir sur le forum bien plus tôt ça m'aurai évité tant de temps perdu
Rebonjour, après plusieurs tests, je m'aperçois que ce n'est toujours pas bon en fait.

Je n'arrive pas, par exemple, à sélectionner la valeur du moment actuel ainsi que celle de l'heure d'avant.

Est-ce que quelqu'un aurait l'amabilité de montrer un exemple qui fonctionne dans tous les cas de figure présentés précédemment. Merci d'avance.
Modifié par lorenzo_one (01 Sep 2011 - 10:16)
La fonction SQL pour obtenir le DATETIME actuel est NOW().

Avec ce qui a été dit auparavant, tu n'as normalement besoin de rien de plus Smiley smile
Bonjour à tous, j'ai trouver un lien fort utile qui après quelques modifications m'a permis de faire face aux différents problèmes de dates.

Le voici au cas où ça intéresse quelqu'un :
http://blog.developpez.com/elsuket/p9840/snippets/trouver-le-premier-et-le-dernier-jour-de/

Par contre, je n'arrive pas du tout à utiliser la fonction IFNULL pour palier au problème des données non existantes avant le 1er janvier.

Si quelqu'un a une idée je suis preneur, merci!
Au niveau des dates c'est bon merci car j'ai résolu mon problème.

Par contre, lorsque je dois aller chercher une valeur dans ma table à une date non créée, je souhaiterai renvoyer un 0. Apparemment, cela est possible avec la fonction IFNULL(d, val_d'echange) mais ça ne marche pas avec ma requête.

La voici :

$query = 	"SELECT IFNULL(val_conso, 0) AS val_conso FROM $table WHERE TIMESTAMP(date_conso) = TIMESTAMP(NOW() - INTERVAL 1 YEAR)
ORDER BY date_conso ASC"	//sélectionne la dernière valeur de la période souhaitée
or die('Impossible d\'exécuter la requête :' . mysql_error());		//Sinon ce message d'erreur s'affiche		
$result = mysql_query($query); // on place le résultat de la requête dans une variable result
			
while($data = mysql_fetch_array($result)){	//on récupère le résultat dans un tableau nommé data
	echo ($data['val_conso'].'---</br>');
}


Mais ce la ne m'affiche rien et je ne comprends pas
Si tu n'as rien, c'est déjà un souci avec ta clause WHERE.

Attention, aussi, car en php, echo 0 n'affiche rien, contrairement à echo '0'
TIMESTAMP(date_conso) = TIMESTAMP(NOW() - INTERVAL 1 YEAR)

Attention au faux amis. TIMESTAMP ne retourne, de mémoire, PAS le time UNIX.

Cf. UNIX_TIMESTAMP
Non je sais que timestamp renvoie mon expression sous forme d'un datetime. Merci quand même pour l'info.

Par contre, je ne savais pas qu'en PHP echo 0 n'affichait rien je vais essayer en mettant IFNULL(val,'0') pour voir, merci LPU8ER
Non mais. Ca ne changera rien dans ton cas, c'est juste pour l'info, selon les tests que tu fais, car ça aurait du t'afficher "---" avec un saut de ligne, si au moins une entrée avait été trouvée...
OK mais du coup, comment tu ferai si dans ta base tu avais une données pour aujourd'hui, une donnée pour le même jour qu'aujourdhui mais de l'année prochaine et aucune pour l'année précédente, pour comparer la valeur d'aujourd'hui avec celle de l'an passé et retourner 0 en cas de données absente
Ta demande n'est pas assez détaillée.

Donnée = valeur ? Valeur arbitraire ?

Si je comprends bien; imaginons, donc, que je souhaite "obtenir la valeur d'une donnée précise, datant d'un an avant maintenant. Si la valeur de l'année précédente n'est pas trouvée, considérer 0.".

Primo : je pense que c'est contre les statistiques de considérer 0 pour une donnée absente. Mais bref.

Secundo : si mysql ne retrouve aucune valeur, il ne retourne rien. Dans ton exemple, si tu n'avais pas de valeur il y a un an, ta clause WHERE va faire que tu n'as aucun retour. Ce, NULL ou pas. Dans ce genre de cas, justement, tu vas compter le nombre de résultats, si ce nombre est 0, tu n'as pas de datas, donc... '0'.

Si ta requête n'est qu'un ersatz d'une requête avec des LEFT JOIN (par exemple), là ça devient plus intéressant. Auquel cas, imaginons un énoncé:
"obtenir la valeur d'une donnée précise actuelle, ainsi que celle datant d'un an avant maintenant. Si la valeur de l'année précédente n'est pas trouvée, considérer 0."

Auquel cas on aurait quelque chose comme
SELECT ta.pop AS pop_actual, IFNULL(tp.pop, 0) AS pop_past
FROM populations ta
LEFT JOIN populations tp
ON (
  (tp.pays = ta.pays)
  AND
  (TIMESTAMP(tp.date_eval) = TIMESTAMP(ta.date_eval - INTERVAL 1 YEAR))
)
WHERE ta.date_eval = NOW()


Tu vois le souci ? Il te manque un point de référence, un ancrage, forçant au moins un résultat. Si mysql ne trouve rien, il ne renvoie rien, et pas "une ligne de rien". Ici, avec le LEFT JOIN, on a une référence croisée. Si la table ta ne retournait rien, car aucune donnée, on aurait aucun résultat, la requête serait inefficace.
Donc soit tu as un point de repère, d'ancrage, soit tu dois vérifier à posteriori le nombre de résultats pour savoir si oui ou non tu as une donnée. Tu peux également passer par une requête COUNT (ou autres fonctions d'agrégats), mais cela va soit te bloquer pour l'obtention des données, soit te forcer à faire une opération coûteuse en SQL Smiley smile
Modifié par Lpu8er (02 Sep 2011 - 12:22)
Pages :