Problème avec LIMIT et GROUP-CONCAT dans une requete preparée
Résolu/Fermé
christian82000
Messages postés
47
Date d'inscription
dimanche 27 décembre 2009
Statut
Membre
Dernière intervention
17 septembre 2020
-
5 janv. 2018 à 11:55
jordane45 Messages postés 38347 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 24 décembre 2024 - 7 janv. 2018 à 15:21
jordane45 Messages postés 38347 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 24 décembre 2024 - 7 janv. 2018 à 15:21
A voir également:
- Problème avec LIMIT et GROUP-CONCAT dans une requete preparée
- Gd group prélèvement - Forum Vos droits sur internet
- Comment ajouter une personne sur whatsapp dans un groupe - Guide
- Prélèvement inconnu ✓ - Forum Vos droits sur internet
- Il y a eu un problème avec cette requête. nous travaillons à sa résolution aussi vite que nous le pouvons. - Forum Facebook
- Affichez l'ensemble des diapositives à l'écran avec 5 diapositives par ligne. repérez le groupe de 3 diapositives avec une fleur identique alignées verticalement, supprimez la première d'entre elles. un nouveau groupe de 3 diapositives avec une fleur identique alignées verticalement apparaît, supprimez encore la première d'entre elles. déplacez les 3 premières diapositives de la 4e ligne au début de la présentation. quel mot est formé par les lettres de la première colonne ? - Forum Powerpoint
4 réponses
jordane45
Messages postés
38347
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
24 décembre 2024
4 719
Modifié le 5 janv. 2018 à 12:31
Modifié le 5 janv. 2018 à 12:31
Bonjour,
Pourquoi vouloir faire X requêtes ... alors que tu peux en faire une seule qui te donne tout et tu gères l'affichage via tes boucles php...
A moins que ta question c'est d'avoir 20 adresses PAR "Agree"...
Là... il faut modifier la requête (en utilisant les limit )
Un truc du genre
Cordialement,
Jordane
Pourquoi vouloir faire X requêtes ... alors que tu peux en faire une seule qui te donne tout et tu gères l'affichage via tes boucles php...
$sql = 'SELECT agree, GROUP_CONCAT(Courriel SEPARATOR "; ") as mail FROM ce GROUP BY Agree '; try{ $Adresses = $bdd->prepare($sql); $Adresses->execute(); $Contacts=$Adresses->fetchAll(); }catch(Exception $e){ echo "Erreur ! " .$e->getMessage(); } //parcours du résultat de la requete for ($i=0;$i<20;$i++){ echo $Contacts[$i]['mail']; } // second parcours du résultat de la requete for ($i=20;$i<40;$i++){ echo $Contacts[$i]['mail']; }
A moins que ta question c'est d'avoir 20 adresses PAR "Agree"...
Là... il faut modifier la requête (en utilisant les limit )
Un truc du genre
SELECT T.agree, GROUP_CONCAT(T.Courriel SEPARATOR "; ") as mail FROM( SELECT agree, Courriel FROM ce LIMIT :debut, :fin ) T GROUP BY T.Agree
Cordialement,
Jordane
Hou que c'est moche votre façon de faire. Normal quand on débute et qu'on Ces 3 ensembles distincts(le plus possible) se nomment architecture 3 tiers(ou tripartie).
L'intérêt est que le http(le web quoi) peut accéder à la base de données indirectement(via PHP) mais que la base de données elle même n'est jamais accessible directement par Internet. Cela garantit la sécurité de celle ci avec un minimum de règles de PHP.
Concrètement une base de données possède un langage rudimentaire de programmation, langage de requêtes nommé S.Q.L. => Structured Query Language.
Donc quand vous parlez de requêtes il ne s'agit pas de PHP mais de SQL.
SQL donc 1)chacun et son rôle et attribuez les rôles.
2) Si la question concerne une requête(obtention, modification, tri, classement des données de la base) la réponse est SQL. Si la réponse concerne l'affichage ou la logique du programme ainsi que l'obtention des données d'un formulaire la réponse est PHP. Ce qui implique la plupart du temps la fonction PHP echo a pour effet d'afficher dans le HTML.
La passerelle n'est pas imagée elle est bien concrète: de la page web vers la base et dans l'autre sens.
Sans vouloir rentrer dans le détail pour expliquer tout les problèmes votre structure qui mélange du PHP et du SQL pour un même qui est du pur SQL c'est un non sens et une erreur de conception. Je citerais toutefois l'inutile complexité du code, la perte de temps d’exécution de 2 serveurs qui n'ont rien en commun(Apache et le serveur de la base) mais bon il en existe d'autres qui sont assez triviaux.
Bref comme le laisse suggérer l'intitulé de la question la réponse étant SQL(la fonction LIMIT) est simplement ici:
http://sql.sh/cours/limit
Notez qu'une technique de débug simple est de vérifier ses requêtes directement sur le serveur SQL(ex: avec WAMP/easyPHP ou par la console). Vous verrez vite: La requête donne le bon résultat directement sur la base l'erreur vient du côté PHP ou si la requête ne donne pas le résultat escompté c'est la requête qui est à refaire.
L'intérêt est que le http(le web quoi) peut accéder à la base de données indirectement(via PHP) mais que la base de données elle même n'est jamais accessible directement par Internet. Cela garantit la sécurité de celle ci avec un minimum de règles de PHP.
Concrètement une base de données possède un langage rudimentaire de programmation, langage de requêtes nommé S.Q.L. => Structured Query Language.
Donc quand vous parlez de requêtes il ne s'agit pas de PHP mais de SQL.
SQL donc 1)chacun et son rôle et attribuez les rôles.
2) Si la question concerne une requête(obtention, modification, tri, classement des données de la base) la réponse est SQL. Si la réponse concerne l'affichage ou la logique du programme ainsi que l'obtention des données d'un formulaire la réponse est PHP. Ce qui implique la plupart du temps la fonction PHP echo a pour effet d'afficher dans le HTML.
La passerelle n'est pas imagée elle est bien concrète: de la page web vers la base et dans l'autre sens.
Sans vouloir rentrer dans le détail pour expliquer tout les problèmes votre structure qui mélange du PHP et du SQL pour un même qui est du pur SQL c'est un non sens et une erreur de conception. Je citerais toutefois l'inutile complexité du code, la perte de temps d’exécution de 2 serveurs qui n'ont rien en commun(Apache et le serveur de la base) mais bon il en existe d'autres qui sont assez triviaux.
Bref comme le laisse suggérer l'intitulé de la question la réponse étant SQL(la fonction LIMIT) est simplement ici:
http://sql.sh/cours/limit
Notez qu'une technique de débug simple est de vérifier ses requêtes directement sur le serveur SQL(ex: avec WAMP/easyPHP ou par la console). Vous verrez vite: La requête donne le bon résultat directement sur la base l'erreur vient du côté PHP ou si la requête ne donne pas le résultat escompté c'est la requête qui est à refaire.
jordane45
Messages postés
38347
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
24 décembre 2024
4 719
6 janv. 2018 à 00:10
6 janv. 2018 à 00:10
Je me demande si un code de ce genre ne ferait pas l'affaire...
NB: Je l'ai codé de tête... il peut y avoir des erreurs qu'il faudra corriger.....
<?php // Récupération de toutes les adresses function getAllContacts(){ global $bdd; $sql = 'SELECT agree, Courriel FROM ce ORDER BY Agree '; try{ $prepare = $bdd->prepare($sql); $prepare->execute(); $result = $Adresses->fetchAll(); }catch(Exception $e){ echo "Erreur ! " .$e->getMessage(); } return !empty($result) ? $result : NULL ; } //Fonctions pour réorganiser l'array des mails function reorderListMails($Contacts=array()){ $arr_contacts = array(); if(!empty($Contacts)){ //on boucle sur l'array des Contacts foreach($Contacts as $C){ $arr_contacts[$C['agree']][] = $C['Courriel']; } } return !empty($arr_contacts) ? $arr_contacts : NULL; } //Fonctions pour générer les blocs de 20 adresses par agree function getBlocsListMails($a_contacts=array()){ foreach($a_contacts as $agree => $mails){ echo "<pre>".$agree."<br>"; $a_adressesMails = getGroupeListeMails($mails,0,19); if(!empty($a_adressesMails)){ foreach($a_adressesMails as $k=>$emails){ echo "<br>".$emails; } } echo "</pre>"; } } //génère des liste de 20 mails function getGroupeListeMails($a_mails = array() , $start = 0,$end = 19 ){ $a_listMails = array(); $strMails = array(); //on vérifie que la variable end est inférieur ou égale au nombre max de mails présents dans l'array $end = $end <= count($a_mails) ? $end : count($a_mails); //on génère le bloc for($i=$start;$i<=$end;$i++){ $a_listMails[] = $a_mails[$i]; } $strMails[] = array(join(",",$a_listMails)); if($end <= count($a_mails) ){ //si il reste des adresses.. on passe au 20 suivantes $strMails[] = getGroupeListeMails($a_mails,$end+1,$end + 20); }else{ return $strMails; } } //------------------------------------------------// // Début du script : //------------------------------------------------// $Contacts = getAllContacts(); //le temps des tests : print_r($Contacts); $arr_mails = reorderListMails($Contacts); //le temps des tests : print_r($arr_mails); getBlocsListMails($arr_mails);
NB: Je l'ai codé de tête... il peut y avoir des erreurs qu'il faudra corriger.....
christian82000
Messages postés
47
Date d'inscription
dimanche 27 décembre 2009
Statut
Membre
Dernière intervention
17 septembre 2020
7 janv. 2018 à 15:16
7 janv. 2018 à 15:16
Bonjour à tous,
Pour Veltur,
J'ai bien compris les conseils que tu m'a donné. Il me semble que je n'étais pas si loin de tes conceptions architecturales : SQL d'une part et PHP d'autre part. Mon problème provenait bien initialement de la conception de la requête SQL, l'imbrication des 2 ne se faisant pas dans le bon ordre. Ensuite, et seulement ensuite, il y a eu un problème d'affichage PHP...
J'avais parcouru le site : https://sql.sh/cours/limit mais je n'y avais pas trouvé la réponse à ma question : comment faire cohabiter les fonctions GROUP_CONCAT() et LIMIT() dans une requête préparée, toutes deux relevant du SQL (seulement MySQL pour GROUP_CONCAT). Pas plus que sur d'autres sites ou forum que j'avais parcouru. Me voila donc sur le forum MySQL de Comment ça marche! Mais le sujet a été déplacé depuis sur le forum PHP.
En tout cas, merci pour t'être intéressé à mon problème.
Pour Jordane.
Tu me propose une solution intéressante avec 3 fonctions. Testée, il y avait au moins 2 bugs (mais tu avais prévenu) et qui, après débogage, doit fonctionner. Mais en fait, mon script est plus complexe que celui que j'ai publié, car il y a 4 alternatives possibles, avec 2 variables présentes ou pas, seules ou conjointes... Ces variables font l'objet de "where" présent ou pas. Mais ce problème est résolu. En fait, je n'ai pas su adapter tes fonctions à cette problématique.
Je me suis donc contenté d'adapter la 2è proposition de ton premier message, et là, tout fonctionne correctement.
Je n'ai pas très bien compris le "T" présent dans le premier SELECT mais apparemment, c'est lui qui fait fonctionner l'ensemble des 2 requêtes imbriquées. J'ai eu beau vérifier sur les cours en ligne ou sur les forums, je n'ai pas trouvé l'explication.
Donc, un grand merci pour t'être penchée sur mon problème et m'avoir conduit vers une solution fonctionnelle.
Je mets le sujet en résolu.
Pour ceux qui seraient intéressé par le code adopté, le voici :
PS : Le tri{} casch{} est contenu dans le script de connexion à la base. Est-il vraiment utile de le reprendre dans la requête SQL?
Bien cordialement
Christian
Pour Veltur,
J'ai bien compris les conseils que tu m'a donné. Il me semble que je n'étais pas si loin de tes conceptions architecturales : SQL d'une part et PHP d'autre part. Mon problème provenait bien initialement de la conception de la requête SQL, l'imbrication des 2 ne se faisant pas dans le bon ordre. Ensuite, et seulement ensuite, il y a eu un problème d'affichage PHP...
J'avais parcouru le site : https://sql.sh/cours/limit mais je n'y avais pas trouvé la réponse à ma question : comment faire cohabiter les fonctions GROUP_CONCAT() et LIMIT() dans une requête préparée, toutes deux relevant du SQL (seulement MySQL pour GROUP_CONCAT). Pas plus que sur d'autres sites ou forum que j'avais parcouru. Me voila donc sur le forum MySQL de Comment ça marche! Mais le sujet a été déplacé depuis sur le forum PHP.
En tout cas, merci pour t'être intéressé à mon problème.
Pour Jordane.
Tu me propose une solution intéressante avec 3 fonctions. Testée, il y avait au moins 2 bugs (mais tu avais prévenu) et qui, après débogage, doit fonctionner. Mais en fait, mon script est plus complexe que celui que j'ai publié, car il y a 4 alternatives possibles, avec 2 variables présentes ou pas, seules ou conjointes... Ces variables font l'objet de "where" présent ou pas. Mais ce problème est résolu. En fait, je n'ai pas su adapter tes fonctions à cette problématique.
Je me suis donc contenté d'adapter la 2è proposition de ton premier message, et là, tout fonctionne correctement.
Je n'ai pas très bien compris le "T" présent dans le premier SELECT mais apparemment, c'est lui qui fait fonctionner l'ensemble des 2 requêtes imbriquées. J'ai eu beau vérifier sur les cours en ligne ou sur les forums, je n'ai pas trouvé l'explication.
Donc, un grand merci pour t'être penchée sur mon problème et m'avoir conduit vers une solution fonctionnelle.
Je mets le sujet en résolu.
Pour ceux qui seraient intéressé par le code adopté, le voici :
<?php $debut=0; $fin=20; while($debut<300) { $Adresses = $bdd->prepare('SELECT T.Agree, GROUP_CONCAT(T.Courriel SEPARATOR "; ") as mail FROM ( SELECT Agree, Courriel FROM ce LIMIT :debut, :fin) T GROUP BY T.Agree'); $Adresses->bindValue(':debut',$debut, PDO::PARAM_INT); $Adresses->bindValue(':fin',$fin, PDO::PARAM_INT); $Adresses->execute(); $Contacts = $Adresses->fetch(); echo $dest=$Contacts['mail']; if($dest == null) { exit(); } $debut+=20 } ?>
PS : Le tri{} casch{} est contenu dans le script de connexion à la base. Est-il vraiment utile de le reprendre dans la requête SQL?
Bien cordialement
Christian
jordane45
Messages postés
38347
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
24 décembre 2024
4 719
7 janv. 2018 à 15:21
7 janv. 2018 à 15:21
Je n'ai pas très bien compris le "T" présent dans le premier SELECT mais apparemment, c'est lui qui fait fonctionner l'ensemble des 2 requêtes imbriquées. J'ai eu beau vérifier sur les cours en ligne ou sur les forums, je n'ai pas trouvé l'explication
C'est ce qu'on appel un ALIAS
Au même titre que tu peux mettre des ALIAS à tes champs dans ta requête (en faisant un AS )... tu peux (dois) mettre des ALIAS sur tes tables (surtout quand tu utilises des sous-requêtes comme c'est le cas ici )
PS : Le tri{} casch{} est contenu dans le script de connexion à la base. Est-il vraiment utile de le reprendre dans la requête SQL?
Alors ce n'est pas tri et casch .. mais TRY et CATCH
Ensuite... celui de la connexion... sert ... pour la connexion.
Ensuite.. tu dois en avoir un pour CHAQUE requête. C'est grâce à ça que tu peux "attraper" / intercepter (catch ) les éventuelles erreurs.
5 janv. 2018 à 14:40
La question est d'avoir les adresses courriel des Agree par groupe de 20 regroupé sur une seule ligne, afin d'envoyer des mssages aux adhérents d'une association (au nombre de 260) en s'affranchissant des contraintes de l'hébergeur en nombre de message par eure et nombre de destinataire par message.
Le problème n'est pas résolu par ta proposition: affichage de l'ensemble des courriels (avec la limitation à 1024 bits propre à GROUP_CONTAT) et affichage du message d'erreur :
( ! ) Notice: Undefined offset: 1 in C:\wamp64\www\xxxxxxx\Mail\EnvoiMessage.php on line 16.
(J'ai traduit le numéro de ligne par rapport à ta proposition de code et ixé le nom du site).
5 janv. 2018 à 15:10
Avant ta requête
Mais de toutes façons... vu ta demande ... ça serait plus ma seconde réponse qui conviendrait
5 janv. 2018 à 15:04
On a donc d'abord l'affichage de l'ensemble des courriels, puis ensuite 20 fois le message d'erreur.
5 janv. 2018 à 23:00
La solution au problème avance: maintenant les 20 1ère lignes sont bien affichées mais la boucle s'arrête et elle n'affiche pas les blocs suivants de 20 entrées. Voici le code :
5 janv. 2018 à 23:31
Au passage... tu as retiré le bloc try/catch que je t'avais ajouté...
Je t'invite à appliquer ceci : https://forums.commentcamarche.net/forum/affich-37584941-php-pdo-gerer-les-erreurs