Bonjour, j'aurais avoir une idée de comment procéder pour( par exemple une fois qu'on arrive en bas d'une table de données récupérées via une requête) afficher la suite.
Je vais essayer d'être un peu plus clair:
comment faire pour sur la requête suivante sur un appui sur un bouton, modifier la requête?
L'idée étant d'associé à des boutons (page suivante, page précédente) la possibilité de visualiser pour le bouton page suivante les jours de 20 à 40, de 40 à 60,..
Faut-il tout simplement créer une nouvelle page pour chaque affichage ce n'est pas très sympa car si on a énormément de données stockées on explose les pages (ce n'est viable que pour 2 ou 3 pages)
Ou peut-on remplacer now et interval 20 day par des variables puis les mettre à jour dans la requête en l'actualisant via du javascript?
Cela me semblerait bien plus "informatique" et propre!
$requete = $bdd->query('SELECT DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ) AS horodatage,M.id_ruche,MH.temperature, ROUND(AVG(M.mas),2) AS poids
FROM Telemesures_ruches M INNER JOIN (-- Moyennes temperature
SELECT DATE_FORMAT( horodatage, "%d-%m-%Y %H:00" ) AS point_horaire,
ROUND(AVG(tex),1) AS temperature FROM Telemesures_ruches WHERE horodatage >= NOW() - INTERVAL 20 DAY
GROUP BY DATE_FORMAT( horodatage, "%d-%m-%Y %H:00" ) ) AS MH ON DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ) = MH.point_horaire
WHERE M.horodatage >= NOW() - INTERVAL 20 DAY GROUP BY DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ), M.id_ruche, MH.temperature
ORDER BY DATE_FORMAT( M.horodatage, "%Y-%m-%d %H:00" ) DESC, M.id_ruche');
Bon si tu reprends ce que j'ai dit dans ton precedent post tu devrais pas avoir de probleme.
Tu ecris tes requetes dans une meme fonction, ou meme page, comme tu veux.
Tu connectes les boutons precis a une meme fonction(ou plusieurs selon ton choix) en javascript. Cette fonction va lancer une requete ajax(fetch) vers ta page php contenant tes requetes et en fonction d'un parametre present dans la requete envoyeee au php, tu executera une requete sql precise et retournera le resultat.
Si j'ai bien compris (?) tu veux faire de la pagination. Il ne s'agit pas de modifier la requête mais juste d'accéder aux items suivants suivant l'ordre de ta requête. Donc tu prends la plage complète de date et au fur et à mesure tu déroules les infos.
Donc cherche avec pagination, il y a plein de tutos.
Merci pour vos réponses, il ne s'agit pas de pagination, et je ne voudrais pas écrire 36 milles requêtes.
Je n'ai pas été trop clair, mais je ne voyais pas trop comment m'exprimer sur ce sujet...
Je vais réessayer.
Pourquoi si possible éviter la solution d'une requête tous les 15 jours... Parce que ma base contient déjà presque un an de données avec l'objectif de continuer de nombreuses années! (espérons le)
Du coup si je devais faire une requête différente par vingtaine de jour de données à afficher cela risque d'être un peu le bazard il faudrait en rajouter 18 par an...
C'est pourquoi j'aurais souhaité (si c'est faisable) pouvoir remplacer (dans la requête initiale (dans mon 1er post) qui va de maintenant à - 20 jours))
now et -20 par des variables qui au chargement de la page serait donc = à now et l'autre égale à -20 puis sur clique sur d'un bouton "suivant" en bas à droite de page (donc en fin de la table d'affichage des 20 premiers jours) pouvoir remonter en haut de page (ça pas trop de soucis) et relancer la même requête mais avec comme interval non plus now et -20 mais de -21 à -40 jours et ainsi de suite...
Avec bien entendu une fois la page initiale quittée, l'apparition d'un deuxième bouton (en bas à gauche) qui lui permette la même chose mais dans le sens inverse.
Bref j'envisage un affichage d'une page contenant 20 jours de données. Avec des boutons de navigation pour augmenter la consultation des données dans le temps. Je ne veux pas mettre toutes les données sur une seule page cela rendrait le défilement bien trop long (déjà 20 jours c'est beaucoup j'envisage de passer à 15 jours)
La page initiale est actuellement fonctionnelle, avec une seule requête dans la page, mais qui ne permet que l'affichage des 20 derniers jours ...
Je recherche un truc de ce genre : (qui ici bien sur ne fonctionne pas)
Tu n'as pas compris ce que @monkey3d veut dire. Avec la pagination tu dois pas forcement recevoir toutes les donnees et n'afficher que quelques.
Tu peux , comme dans ton cas faire une requete pour une "periode" precise. Ainsi page.php?p=17 va afficher la page 17, chaque page contenant X lignes.
C'est possible avec uniquement php, ce qui est mieux d'ailleurs que de faire appel au Js pour ci peu. Jette souven un coup d'oeil aux liens qu'il envoie avant de continuer...
Cela traite de la découpe en page suite à une requête globale (qui du coup sélectionne toutes les données de la table) sur l'ensemble des données dont on a besoin d'afficher puis découpe en sous ensembles pour les afficher sur des pages différentes.
Mais cela ne risque t-il pas de prendre énormément de temps sur une table déjà conséquente de faire à chaque fois une extraction globale pour ne pas forcement consulter toutes les pages?
Ta requete doit avoir une structure de base avec une ou deux variables qui changent a chaque fois. Si j'ai bien compris dans ta requete si l'utilisateur veut la page 1, il va avoir les donnees de NOW a NOW - 20, pour la page 2 c'est NOW - 21 a NOW - 40. Donc page k => NOW - 20 * (k-1) - NOW - 20 * k.
Je pense que tu as une idee de la requete a faire, suivant les tutos du dessus.
Je ne veux pas l'heure actuelle mais la date et l'heure du dernier enregistrement rentré dans la table.
C'est ce que me retourne cette requête :
$test = $bdd->query("SELECT DATE_FORMAT(horodatage, '%d/%m/%Y %Hh%i:%s') AS date_formatee FROM Telemesures_ruches WHERE horodatage >= NOW() - INTERVAL 15 MINUTE ORDER BY horodatage DESC");
$maint = $test->fetch();
echo 'now= '.$maint['date_formatee'];
Et cette requête pour connaitre le premier enregistrement mais 15 jours plus tôt :
$test = $bdd->query("SELECT DATE_FORMAT(horodatage, '%d/%m/%Y %Hh%i:%s') AS date_formatee FROM Telemesures_ruches WHERE horodatage >= NOW() - INTERVAL 15 DAY ORDER BY horodatage ASC LIMIT 1");
$jours = $test->fetch();
echo ' 15jours plus tôt = '.$jours['date_formatee'];
J'aimerais pouvoir faire une requête ou je pourrais remplacer par exemple le >= NOW() par $jours['date_formatee']
exemple qui ne fonctionne pa
$reponse = $bdd->query("SELECT * , DATE_FORMAT(horodatage, '%d/%m/%Y %Hh%i:%s') AS date_formatee FROM Telemesures_ruches WHERE (id_ruche) = $NumRuche AND horodatage >= $jours['date_formatee'] - INTERVAL 2 WEEK ORDER BY horodatage DESC");
Pour du coup dans cet exemple extraire les données depuis le premier enregistrement d'il y a 15 jours jusqu'à 2 semaines plus tôt...
Merci, je n'ai pas encore eu le temps de regarder (beaucoup de boulot avec les abeilles et le jardin...)
On m'a aussi suggéré ceci : (qui fonctionne en faisant un copié*collé dans le SQL de ma base.
Ex pour tester dans un requêteur :
SET @N=0;
set @NumRuche=1;
SELECT
* , DATE_FORMAT(horodatage, '%d/%m/%Y %Hh%i:%s') AS date_formatee
FROM Telemesures_ruches WHERE (id_ruche) = @NumRuche
AND horodatage BETWEEN date_add(current_timestamp, interval -15*(@n+1) minute)
AND date_add(current_timestamp, interval -15*(@n) minute)
afficher non pas 10 données par page mais les données d'une journée (ou 15 jours) par page ?
La requête proposée au dessus est une bonne base. Tu peux paramétrer le nombre et le type de l'intervalle. Je te conseille de le faire en PHP pour mieux gérer l'affichage :
Dans ta page PHP, il faudra que tu ajoutes des inputs permettant de modifier les valeurs des 4 variables au début de ce code, avec une balise <select> pour le type (MINUTE, DAY, MONTH, YEAR), et un bouton "Voir ces données" ...
$sql = '
SELECT *, DATE_FORMAT(horodatage, '%d/%m/%Y %Hh%i:%s') AS date_formatee
FROM Telemesures_ruches
WHERE
id_ruche = ?
AND horodatage
BETWEEN DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($taille_intervalle).' * ( '.intval($decalage_intervalle).' + 1 ) '.$type_intervalle.' )
AND DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($taille_intervalle).' * '.intval($decalage_intervalle).' '.$type_intervalle.' );';
J'ai un doute sur le ; avant le '; mais cela ne change rien, j'ai essayé de remplacer directement les '.intval($t...).' par leurs valeurs cela donne ceci :
J'ai aussi remplacé l'apostrophe de début et de fin par un guillemet sinon avec l'apostrophe du %d/%... cela ne doit pas coller..
$sql = " SELECT *, DATE_FORMAT(horodatage, '%d/%m/%Y %Hh%i:%s') AS date_formatee
FROM Telemesures_ruches WHERE id_ruche = ?
AND horodatage BETWEEN DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - 15 * ( 10+ 1 ) MINUTE)
AND DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - 15 * 10 MINUTE )";
Mais du coup la page tourne avec ce message d'erreur :
string(286) " SELECT *, DATE_FORMAT(horodatage, '%d/%m/%Y %Hh%i:%s') AS date_formatee FROM Telemesures_ruches WHERE id_ruche = ? AND horodatage BETWEEN DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - 15 * ( 10+ 1 ) MINUTE) AND DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - 15 * 10 MINUTE )"
Salut, non je pense que c'est bien horodatage après le where, car cette requête fonctionne nickel :
reponse = $bdd->query("SELECT * , DATE_FORMAT(horodatage, '%d/%m/%Y %Hh%i:%s') AS date_formatee FROM Telemesures_ruches WHERE (id_ruche) = $NumRuche AND horodatage >= NOW() - INTERVAL 2 WEEK ORDER BY horodatage DESC");
Mais je n'oublie pas ton code dès que je serais en vacances (un peu plus d'une semaine) je regarderai cela et je te dirais ce qu'il en est!
Le code a tester dans un requêteur provient d'un ingénieur en informatique comme il était livré tout près au test je n'ai eu qu'à le tester ce qui a été assez rapide...
Merci
Bon il fait vraiment chaud du coup j'ai testé ton idée comme ceci (en espérant ne pas avoir fait de bétises):
$start = 15;
$end = $start + 14; //14 pour deux semaines
$date_debut = new DateTime();
$date_debut->sub(DateInterval::createFromDateString("$start days");
$date_fin = new DateTime();
$date_debut->sub(DateInterval::createFromDateString("$end days");
$reponse = $bdd->query("SELECT * , DATE_FORMAT(horodatage, '%d/%m/%Y %Hh%i:%s') AS date_formatee FROM Telemesures_ruches WHERE (id_ruche) = 1 AND horodatage BETWEEN $date_debut AND $date_fin");
cela me donne un erreur serveur 500: il y a donc un couac dans la requête...
Alors la requête fonctionne ... Elle s'affiche via le var_dump, mais il faut ensuite boucler sur $donnees pour les afficher ... ce que je n'ai pas mis dans le code ... mais j'espère que tu le fais à la suite
Et elle fonctionne bien, il faut juste que tu apprennes à dompter les variables
Si tu mets 10, 15 et DAY, la requête va te sortir les mesures prises entre 165 ( 15 x ( 10 + 1 ) ) et 150 ( 15 x 10 ) jours avant aujourd'hui. A mon avis tu n'en as pas en base de si vieux ...
Effectivement je n'ai pas fait attention je n'ai des données sur la ruche 1 que depuis le 16 février...
C'était fait la boucle pour l'affichage (puisque copie écran sur Minute OK)
<?php
while ($donnees = $reponse->fetch())
{
if ($donnees['lum']<>'-1' AND $donnees['eau']<>'-1'){ // cas ou on a tous les capteurs
echo '<tr><td>'.$donnees['date_formatee'].'</td><td>'.$donnees['hyg'].'%</td><td>'.$donnees['tex'].'°C</td><td>'.
$donnees['tin'].'°C</td><td>'.$donnees['mas'].'Kg</td><td>'.$donnees['lum'].'%</td><td>'.$donnees['eau'].'</td></tr>';
}
if ($donnees['lum']=='-1' AND $donnees['eau']=='-1'){ // cas ou on a pas de capteur de luminosité ni de pluie
echo '<tr><td>'.$donnees['date_formatee'].'</td><td>'.$donnees['hyg'].'%</td><td>'.$donnees['tex'].'°C</td><td>'.
$donnees['tin'].'°C</td><td>'.$donnees['mas'].'Kg</td><td>'.'-</td><td>'.'-</td></tr>';
}
if ($donnees['eau']=='-1'AND $donnees['lum']<>'-1' ){ // cas ou on a pas le capteur de pluie mais on a le capteur de luminosité
echo '<tr><td>'.$donnees['date_formatee'].'</td><td>'.$donnees['hyg'].'%</td><td>'.$donnees['tex'].'°C</td><td>'.
$donnees['tin'].'°C</td><td>'.$donnees['mas'].'Kg</td><td>'.$donnees['lum'].'%</td><td>'.'-</td></tr>';
}
if ($donnees['lum']=='-1'AND $donnees['eau']<>'-1'){ //cas ou on a pas le capteur de luminosité mais on a le capteur de pluie
echo '<tr><td>'.$donnees['date_formatee'].'</td><td>'.$donnees['hyg'].'%</td><td>'.$donnees['tex'].'°C</td><td>'.
$donnees['tin'].'°C</td><td>'.$donnees['mas'].'Kg</td><td>'.'-</td><td>'.$donnees['eau'].'</td></tr>';
}
}
?>
J'ai commenté le var_dump( $sql ); cela fonctionne toujours mais plus d'affichage du contenu "texte" de la requête cela ne sert qu'a afficher la requête pour le debug?
Bon j'ai remis l'ordre décroissant du temps comme ceci :
$decalage_intervalle = 0;
$taille_intervalle = 15;
$type_intervalle = 'DAY';
$sql = ' SELECT *, DATE_FORMAT( horodatage, "%d/%m/%Y %Hh%i:%s" ) AS date_formatee FROM Telemesures_ruches WHERE id_ruche = ?
AND horodatage BETWEEN DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($taille_intervalle).' * ( '.intval($decalage_intervalle).' + 1 ) '.$type_intervalle.' )
AND DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($taille_intervalle).' * '.intval($decalage_intervalle).' '.$type_intervalle.' ) ORDER BY horodatage DESC ';
var_dump( $sql ); //permet l'affichage texte de la requête
$reponse = $bdd->prepare( $sql );
$reponse->execute( [ $NumRuche ] );
En supprimant le fameux ; après )
Je vais finalement aussi me servir pour la partie pagination de l'aide fournie par Monkey3D avec ce lien :
Car après discussion il s'avère que finalement recharger une nouvelle page est plus facile à programmer et à gérer!
Merci
Vu la chaleur extérieure j'ai un peu bidouillé à l'intérieur
Du coup j'ai adapté à ma table, l'exemple du lien ci dessus à ma base (en refaisant les GET car j'en avais déjà en place), cela fonctionne nickel:
// nombre de lignes à afficher
$limite = 10;
// ici on calcule le nombre total d'entrée dans la table!
$resultFoundRows = $bdd->query('SELECT count(DISTINCT id_mesure) FROM Telemesures_ruches');
/* On doit extraire le nombre du jeu de résultat */
$nombredElementsTotal = $resultFoundRows->fetchColumn();
//echo $nombredElementsTotal;
// numéro de page actuelle et si vide attribue la page 1
$page = (!empty($_GET['page']) ? $_GET['page'] : 1);
$page = intval($_GET['page']); // Conversion forcée en entier
// Si le nombre est invalide, on demande la première page par défaut
if($page <= 0) {
$page = 1;
}
/* On calcule le numéro du premier élément à récupérer */
$debut = ($page - 1) * $limite;
// calcul du nombre total de pages possible en fonction de limite
$nombreDePages = ceil($nombredElementsTotal / $limite);
//echo $nombreDePages ;
// Partie "Requête"
/* On construit la requête, en remplaçant les valeurs par des marqueurs. Ici, on
* n'a qu'une valeur, limite. On place donc un marqueur là où la valeur devrait se
* trouver, sans oublier les deux points « : » */
$reponse= 'SELECT * , DATE_FORMAT( horodatage, "%d/%m/%Y %Hh%i:%s" ) AS date_formatee FROM Telemesures_ruches WHERE (id_ruche) =' .$NumRuche.' ORDER BY horodatage DESC LIMIT :limite OFFSET :debut';
//var_dump( $reponse ); //permet l'affichage texte de la requête
/* On prépare la requête à son exécution. Les marqueurs seront identifiés */
$reponse = $bdd->prepare($reponse);
/* On lie ici une valeur à la requête, soit remplacer de manière sûre un marqueur par
* sa valeur, nécessaire pour que la requête fonctionne. */
$reponse->bindValue(
'limite', // Le marqueur est nommé « limite »
$limite, // Il doit prendre la valeur de la variable $limite
PDO::PARAM_INT // Cette valeur est de type entier
);
/* … auquel il faut aussi lier la valeur, comme pour la limite */
$reponse->bindValue('debut', $debut, PDO::PARAM_INT);
/* Maintenant qu'on a lié la valeur à la requête, on peut l'exécuter */
$reponse->execute();
// Partie "Liens"
/* Si on est sur la première page, on n'a pas besoin d'afficher de lien
* vers la précédente. On va donc ne l'afficher que si on est sur une autre
* page que la première */
if ($page > 1):
?>
<a href="?ruche=<?php echo $NumRuche?>&p=donneestest&page=<?php echo $page - 1; ?>"><img src="images/fleche_gauche_rouge.png"/></a>
<?php
endif;
/* Avec le nombre total de pages, on peut aussi masquer le lien vers la page suivante quand on est sur la dernière */
if ($page < $nombreDePages):
?>
<div style="float: right ">
<a href="?ruche=<?php echo $NumRuche?>&p=donneestest&page=<?php echo $page + 1; ?>"><img src="images/fleche_droite_rouge.png"/></a>
</div>
<?php
endif;
?>
Mais ici le nombre d'affichage se fait par un nombre fixé ($limite).
J'ai essayé de modifier l'exemple pour pouvoir au lieu de paginer sur un nombre de données fixe pouvoir travailler sur des dates (en gros afficher 15 jours par page). j'ai donc essayer une "combinaison" des 2 requêtes
Bon je progresse doucement :
$reponse= 'SELECT * , DATE_FORMAT( horodatage, "%d/%m/%Y %Hh%i:%s" ) AS date_formatee FROM Telemesures_ruches WHERE (id_ruche) =' .$NumRuche.'
AND horodatage BETWEEN DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * ( '.intval($debut).' + 1 ) '.$type_intervalle.' )
AND DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * '.intval($debut).' '.$type_intervalle.' )ORDER BY horodatage DESC';
Avec cette modification
/* On calcule le numéro du premier élément à récupérer */
$debut = ($page - 1) ;
Il faut que je contrôle plus mais cela a l'air presque bon!
Il me reste encore à trouver comment calcule le nombre de page...
J'ai modifié ma requête pour compter le nombre d'entrée totale pour ne l'appliquer que sur une ruche ça c'est bon :
// ici on calcule le nombre total d'entrée dans la table!
$resultFoundRows = $bdd->query("SELECT count(DISTINCT id_mesure) FROM Telemesures_ruches WHERE (id_ruche) = $NumRuche");
Mais l'ancienne méthode de calcul du nombre de page, elle n'est plus adaptée :
// calcul du nombre total de pages possible en fonction de limite
$nombreDePages = ceil($nombredElementsTotal / $limite);
Il me faut donc calculer aussi ce que chaque page affiche encore un autre fetchColumn()?
Bon il me reste deux soucis, enfin un + une interrogation :
l'interrogation: pour calculer le nombre de données affichées par ma page n'y a t-il pas mieux que de refaire une requête identique juste pour compter:
// ici on calcule le nombre total d'entrée dans la page!
$nbreponse = 'SELECT COUNT(id_mesure) , DATE_FORMAT( horodatage, "%d/%m/%Y %Hh%i:%s" ) AS date_formatee FROM Telemesures_ruches WHERE (id_ruche) =' .$NumRuche.'
AND horodatage BETWEEN DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * ( '.intval($debut).' + 1 ) '.$type_intervalle.' )
AND DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * '.intval($debut).' '.$type_intervalle.' )ORDER BY horodatage DESC';
Et du coup même si je trouve cette méthode de calcul un peut longue juste pour connaitre le nombre de ligne affichés dans la page, il reste un "bug" :
J'ai actuellement 8 pages complètes de 15 jours de données, la 9 eme page n'est pas entièrement pleine.
Du coup mon calcul sur les 8 premiers pages et bon il me sort bien que je ne peux afficher que 9 pages, mais arrivé sur la 9eme page celle-ci n'étant pas complète il m'affiche que je peux avoir 14 pages... et du coup mon bouton suivant est toujours actif...
Comme la page se recharge à chaque fois que l'on clique sur le bouton suivant, le résultat du calcul du nombre de page possible est refait à chaque chargement.
Je ne vais quand même pas être obligé de mémoriser cette information dans un get non? (paramétrage de la valeur lorsque l'on est sur la 1er page puis on ne change plus la valeur)
Une meilleur idée?
Merci
- Edité par GillesMangin-Voirin 19 juin 2022 à 16:04:02
La variable $decalage_intervalle représente directement le numéro de page, attention, en partant de 0.
Tu ne peux pas déterminer à l'avance le nombre de pages car le nombre de lignes par page est variable. Il te faut donc compter le nombre de lignes de l'intervalle suivant, et ce pour chaque page affichée, et c'est en fonction que tu affiches ou non le bouton "Suivant".
Oui, je suis d'accord c'est pour cela que lorsque je vais sur une nouvelle page ( la page 0) je mets dans l'url &page=1&sur=0
vu que dans le programme je vais ceci : $debut = ($page - 1) ;
Ou $page est le numéro de page actuelle, et $sur le nombre total de page possible. Cette valeur (sur) ne sera remplie que lors du premier appui sur le bouton suivant.
Cela fonctionne bien pour accéder à la page données car dans le menu qui permet d'y aller j'ai mis ceci :
Mais du coup je voulais aussi pouvoir parcourir à l'aide de boutons la page d'accueil qui contient la requête suivante :
// numéro de page actuelle et si vide attribue la page 1
$page = (!empty($_GET['page']) ? $_GET['page'] : 1);
$page = intval($_GET['page']); // Conversion forcée en entier
// Si le nombre est invalide, on demande la première page par défaut
if($page <= 0) {
$page = 1;
}
/* On calcule le numéro du premier élément à récupérer */
$debut = ($page - 1) ;
// Partie "Requête"
// nombre de X type_intervalle à afficher
$limite = 10;
// type d'intervalle, seconds, minute, day, week, month
$type_intervalle = 'DAY';
// requête pour obtenir les données
$requete = 'SELECT DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ) AS horodatage,M.id_ruche,MH.temperature, ROUND(AVG(M.mas),2) AS poids
FROM Telemesures_ruches M INNER JOIN (-- Moyennes temperature
SELECT DATE_FORMAT( horodatage, "%d-%m-%Y %H:00" ) AS point_horaire,
ROUND(AVG(tex),1) AS temperature FROM Telemesures_ruches WHERE horodatage
BETWEEN DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * ( '.intval($debut).' + 1 ) '.$type_intervalle.' )
AND DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * '.intval($debut).' '.$type_intervalle.' )
GROUP BY DATE_FORMAT( horodatage, "%d-%m-%Y %H:00" ) ) AS MH ON DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ) = MH.point_horaire
WHERE M.horodatage
BETWEEN DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * ( '.intval($debut).' + 1 ) '.$type_intervalle.' )
AND DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * '.intval($debut).' '.$type_intervalle.' )
GROUP BY DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ), M.id_ruche, MH.temperature
ORDER BY DATE_FORMAT( M.horodatage, "%Y-%m-%d %H:00" ) DESC, M.id_ruche';
Mais du coup que mon URL est .. indextest.php
j'ai cette erreur :
Notice: Undefined index: page in /var/www/html/indextest.php on line 95
la ligne 95 c'est $page = intval($_GET['page']); // Conversion forcée en entier
A partir du moment ou je rajoute manuellement dans l'url ceci :
.../indextest.php?page=
c'est bon plus d'erreur (logique il y un get page)
J'aurais voulu savoir comment faire en sorte que mon adresse de page d'accueil puisse contenir le ?page=
Je pensais (à tort apparemment) que la ligne $page = (!empty($_GET['page']) ? $_GET['page'] : 1);
forçait la valeur de page à 1 si elle était vide ou inexistante mais il semble qu'il faut quand même que la variable existe dans l'url..
Autre question toujours en rapport avec ce sujet :
j'aimerais faire un select count au plus économe de cette requête :
$requete = 'SELECT DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ) AS horodatage,M.id_ruche,MH.temperature, ROUND(AVG(M.mas),2) AS poids
FROM Telemesures_ruches M INNER JOIN (-- Moyennes temperature
SELECT DATE_FORMAT( horodatage, "%d-%m-%Y %H:00" ) AS point_horaire,
ROUND(AVG(tex),1) AS temperature FROM Telemesures_ruches WHERE horodatage
BETWEEN DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * ( '.intval($debut).' + 1 ) '.$type_intervalle.' )
AND DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * '.intval($debut).' '.$type_intervalle.' )
GROUP BY DATE_FORMAT( horodatage, "%d-%m-%Y %H:00" ) ) AS MH ON DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ) = MH.point_horaire
WHERE M.horodatage
BETWEEN DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * ( '.intval($debut).' + 1 ) '.$type_intervalle.' )
AND DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * '.intval($debut).' '.$type_intervalle.' )
GROUP BY DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ), M.id_ruche, MH.temperature
ORDER BY DATE_FORMAT( M.horodatage, "%Y-%m-%d %H:00" ) DESC, M.id_ruche';
pour connaitre le nombre de ligne par page que celle-ci va me retourner ...
// ici requête pour calculer le nombre total de ligne dans la page!
$nbreponse = 'SELECT COUNT(id_mesure) , DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ) AS horodatage,M.id_ruche,MH.temperature, ROUND(AVG(M.mas),2) AS poids
FROM Telemesures_ruches M INNER JOIN (-- Moyennes temperature
SELECT DATE_FORMAT( horodatage, "%d-%m-%Y %H:00" ) AS point_horaire,
ROUND(AVG(tex),1) AS temperature FROM Telemesures_ruches WHERE horodatage
BETWEEN DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * ( '.intval($debut).' + 1 ) '.$type_intervalle.' )
AND DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * '.intval($debut).' '.$type_intervalle.' )
GROUP BY DATE_FORMAT( horodatage, "%d-%m-%Y %H:00" ) ) AS MH ON DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ) = MH.point_horaire
WHERE M.horodatage
BETWEEN DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * ( '.intval($debut).' + 1 ) '.$type_intervalle.' )
AND DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - '.intval($limite).' * '.intval($debut).' '.$type_intervalle.' )
GROUP BY DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ), M.id_ruche, MH.temperature
ORDER BY DATE_FORMAT( M.horodatage, "%Y-%m-%d %H:00" ) DESC, M.id_ruche';
Et bien entendu cette requête de comptage ne fonctionne pas : j'obtiens une erreur :
Fatal error: Uncaught Error: Call to a member function prepare() on null in /var/www/html/indextest.php:229 Stack trace: #0 {main} thrown in /var/www/html/indextest.php on line 229
ligne 229 : $nbreponse = $bdd->prepare($nbreponse);
la requête contient ceci : (var dump)
"SELECT COUNT(horodatage) , DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ) AS horodatage,M.id_ruche,MH.temperature, ROUND(AVG(M.mas),2) AS poids FROM Telemesures_ruches M INNER JOIN (-- Moyennes temperature SELECT DATE_FORMAT( horodatage, "%d-%m-%Y %H:00" ) AS point_horaire, ROUND(AVG(tex),1) AS temperature FROM Telemesures_ruches WHERE horodatage BETWEEN DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - 10 * ( 0 + 1 ) DAY ) AND DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - 10 * 0 DAY ) GROUP BY DATE_FORMAT( horodatage, "%d-%m-%Y %H:00" ) ) AS MH ON DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ) = MH.point_horaire WHERE M.horodatage BETWEEN DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - 10 * ( 0 + 1 ) DAY ) AND DATE_ADD( CURRENT_TIMESTAMP, INTERVAL - 10 * 0 DAY ) GROUP BY DATE_FORMAT( M.horodatage, "%d-%m-%Y %H:00" ), M.id_ruche, MH.temperature ORDER BY DATE_FORMAT( M.horodatage, "%Y-%m-%d %H:00" ) DESC, M.id_ruche"
Et idem sur l'équivalente mais sans limite d'horodatage pour connaitre le nombre de page maximal possible
Faut-il vraiment garder toutes les conditions le regroupement et le classement?
Ou peut-on simplifier la requête en gardant bien entendu le bon résultat!
J'avais éventuellement pensé (mais ce n'est pas parfait) vu que cette requête a pour objectif d'afficher une ligne par heure, de prendre la plus vieille date dans la base et de faire la différence entre now et la plus vieille date multiplié par 24 (heures).
On obtient le nombre de lignes maximales sauf que si durant plusieurs heures ou jours aucune ruche n'a communiqué dans une heure cela enlève une ligne à chaque manque...
Du coup il faudrait en + contrôler la présence d'au moins une ligne dans la page pour savoir quand cacher le bouton suivant si la page est vide....
Quel est le plus économe en temps de calcul et mémoire et "facilité" de programmation ?
Merci
PS: a bien y réfléchir un select count (id_mesure) n'est peut-être pas très judicieux de ma part vu qu'il s'agit d'une moyenne de plusieurs mesures...) je vais creuser
Toujours dans mes recherches..
j'ai bien réussi à calculer le nombre d'entrée de ma table 243671 mais le nombre d'heures 65 lui ben il est faux..
J'ai essayé ceci :
// ici on calcule le nombre total d'entrée dans la table!
$resultFoundRows = $bdd->query("SELECT count(DISTINCT id_mesure) FROM Telemesures_ruches ");// renvoi le nombre d'entrée attention inferieur au numéro de base d'environ 55 024!
$nbEntree = $resultFoundRows->fetchColumn(); // on compte le nombre de ligne
echo "Nb entrée : ".$nbEntree;
$resultFoundRows1 = $bdd->query('SELECT count(horodatage) FROM Telemesures_ruches GROUP BY DATE_FORMAT( horodatage, "%d-%m-%Y %H:00" ) ');
$nbEntree1 = $resultFoundRows1->fetchColumn(); // on compte le nombre de ligne
echo "Nb entrée1 : ".$nbEntree1;
Merci
- Edité par GillesMangin-Voirin 22 juin 2022 à 21:33:57
Sinon pour compter le nombre de ligne par page, je peux aussi mettre un compteur php avec une variable incrémentée cela fonctionne bien mais quel est le mieux :
un requête select count (que je n'arrive pas à faire.)
ou une variable à incrémenter dans la boucle d'affichage (qui là fonctionne..)
Dans tous les cas se pose toujours le problème de si certains jours il n'y a pas eu de données pendant quelques heures ce chiffre (nb de ligne affichée par la requête change.
ex:
sur 1 jour actuellement , j'ai 25 lignes
sur 2 jours j'ai j'ai 49 lignes mais sur les 10 derniers jours j'ai 238 lignes (car j'ai eu des soucis d'informatique au rucher avec l'orage de grêle) au lieur de (10*24)+1=241 lignes...
Dans une autre page (avec une autre requête) j'avais limité le questionnement du nombre de ligne par page à la première page afin de pouvoir enlever le bouton suivant correctement à la dernière page qui n'est jamais une page complète... Mais du coup ce n'est pas non plus parfait quand il manque des données comme cela a été récemment le cas !
// on memorise le nombre de page juste à la première page
if ($page == 1){
// calcul du nombre de ligne de retour de la requete
$nbreponse = $bdd->prepare($nbreponse);
/* On lie ici une valeur à la requête, soit remplacer de manière sûre un marqueur par sa valeur, nécessaire pour que la requête fonctionne. */
$nbreponse->bindValue(
'limite', // Le marqueur est nommé « limite »
$limite, // Il doit prendre la valeur de la variable $limite
PDO::PARAM_INT // Cette valeur est de type entier
);
/* … auquel il faut aussi lier la valeur, comme pour la limite */
$nbreponse->bindValue('debut', $debut, PDO::PARAM_INT);
/* Maintenant qu'on a lié les valeurs à la requête, on peut l'exécuter */
$nbreponse->execute();
$nbEntree = $nbreponse->fetchColumn(); // on compte le nombre de ligne
//echo "Nombre d'entrée dans la page : ".$nbEntree;
// calcul du nombre total de pages possible en fonction de limite
$sur = ceil($nombredElementsTotal / $nbEntree);//ceil= arrondi au supérieur entier
//echo "Nombre de page possible :".$sur ;
} // fin du if
Merci
- Edité par GillesMangin-Voirin 23 juin 2022 à 8:49:47
Sinon pour compter le nombre de ligne par page, je peux aussi mettre un compteur php avec une variable incrémentée cela fonctionne bien mais quel est le mieux :
un requête select count (que je n'arrive pas à faire.)
ou une variable à incrémenter dans la boucle d'affichage (qui là fonctionne..)
Je m'embrouille dans tes deux precedents messages...
Pourquoi tu n'arrive pas a faire le COUNT dans ton SELECT ? Une erreur ou tu ne recois rien ? Choisir parmi le deux la je ne sais pas, dans les deux cas on compte chaque ligne sauf que dans le premier c'est MySQL qui le fait, vu que tu as beaucoup de donnees est peut-etre preferable, peut-etre.
>Mais du coup ce n'est pas non plus parfait quand il manque des données comme cela a été récemment le cas !
Tu veux afficher les donnees percues sur une periode donnee, avoir le nombre de lignes qui differe d'une page a l'autre est plutot normal. Tu veux alors afficher les donnees d'une autre page si celle de la page actuelle est trop peu ?
× 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.
Et Voila un peu mon idee...