PHP Eviter les doublons

Résolu/Fermé
Jethro - Modifié par Jethro le 24/08/2011 à 23:24
 Alex - 22 sept. 2011 à 14:53
Bonjour,
J'aimerais lister des évènements en les regroupant par date ; jusque là, pas de problèmes.
Sauf que ça me fait des doublons, car le script va chercher, pour un évènements donné, chaque autre évènement qui a la même date. Du coup, pour un autre évènement donné, si le premier a la même date, alors il le réaffiche... Je vois très bien pourquoi, mais pour ce qui est de régler le problème, c'est autre chose...
Donc si quelqu'un peut m'aider, ça pourrait bien m'arranger :)
Je donne mon code :

$select01 = mysql_query("SELECT * FROM event" . $tblid . " ORDER BY date") or die(mysql_error()); 
  
 // On fait une boucle pour lister tous les events 
 while($eventslist = mysql_fetch_array($select01)) 
 { 
  // Ce qui suit fonctionne mais il y a des doublons, car il affiche pour chacun ses équivalents (event1.date = event2.date et event2.date = event1.date) 
  $nombre = 5;  
   
  // On sélectionne tous les events dont la date correspond à celle de l'event clé de la boucle while 
  $select02 = mysql_query("SELECT * FROM event" . $tblid . " WHERE date='" . $eventslist['date'] . "'") or die('Yo die'); 
  $rows = mysql_num_rows($select02); 
  if ($rows == 1) 
  { 
   echo '' . $eventslist['date'] . '<br/>' . $eventslist['date'] . '<br/><br/>'; 
   echo '<br/><br/>'; 
  } 
  else if ($rows >= 1) 
  { 
   echo '' . $eventslist['date'] . '<br/>'; 
   //On fait une boucle qui, dans la boucle, liste tous les events de même de date ensembles 
   while ($listbydate = mysql_fetch_array($select02)) 
   { 
    echo '' . $listbydate['event'] . ''<br/>'; 
   } 
   echo '<br/><br/>'; 
  } 
 } 


Donc tout ça me donne :

Date 1
Event 1

Date 2
Event 2

Date 3
Event 3
Event 4

Date 3
Event 3
Event 4

Date 4
Event 5


Alors que je voudrais simplement

Date 1
Event 1

Date 2
Event 2

Date 3
Event 3
Event 4

Date 4
Event 5


Merci d'avance pour l'aide :)
A voir également:

7 réponses

graffx Messages postés 6506 Date d'inscription jeudi 22 mars 2007 Statut Contributeur Dernière intervention 24 mars 2019 1 973
27 août 2011 à 00:01
je n' ai pas torp suivi ton osuci mais pour eviter les doublons tu as la fonction DISTINCT !

http://www.manuelphp.com/mysql/distinct-optimisation.php
1
Profil bloqué
27 août 2011 à 00:35
Oui ! ou tu mets un disjoin mais c'est pas tout a fait pareil
0
Personne ? Oo
:(
0
Mihawk Messages postés 4313 Date d'inscription mercredi 29 mars 2006 Statut Contributeur Dernière intervention 6 janvier 2015 845
25 août 2011 à 18:24
Salut,
Deux choses : pourquoi te casse à refaire une multitude d'appels MySQL alors que tu obtiens déjà tous les événements classés par date ? Tu as déjà dans ta première réponse SQL tout ce qu'il faut !

Sinon ton problème doit venir tu fais que tu fais un if (==1) suivi d'un else if (>=1). Donc dans le cas où ça vaut 1, tu passes dans les deux. Il faut remplacer le >= par un > tout court.

Mais encore une fois ce code est lourd inutilement.
0
Mihawk Messages postés 4313 Date d'inscription mercredi 29 mars 2006 Statut Contributeur Dernière intervention 6 janvier 2015 845
25 août 2011 à 18:35
Une idée de solution plus propre :

$memDate = 0;   // Sert à retenir la date de l'événement précédent
$memEvenement = "";   // Sert à créer petit a petit le code des événements ayant la même date
$iCompteur = 0;   // Sers uniquement à détecter le premier passage dans la boucle

while($eventslist = mysql_fetch_array($select01)){
   if ($iCompteur > 0){
      if ($eventslist['date'] != $memDate){  //Nouvelle date
         echo ($memDate."<br/>".$memEvenement."<br/><br/>");
         $memDate = $eventslist['date'];
         $memEvenement = "";
      } else { // cas d'une date déjà vue
         $memEvenement = $memEvenement."<br/>".$eventslist['events'] ;
      }
   } else { // cas du premier passage dans la boucle
      $memDate = $eventslist['date'];
      $memEvenement = $eventslist['events'];
   }
   $iCompteur++;
}


Normalement ça doit marcher, mais avec l'éditeur de CCM j'ai pu faire quelques erreurs :)
0
Et sinon, plus simple :
$lastDate = '';
$result = '';

while($row = mysql_fetch_array($select01)){
if( $row['date'] !== $lastDate )
{
$result .= (empty($lastDate)?'':"<br/>").$row['date'];
$lastDate = $row['date'];
}
$result .= "<br/>".$row['event'];
}

( @Mihawk : Autant utiliser la variable de dernière date pour tester s'il s'agit ou non du 1er passage ;) )
0
Mihawk Messages postés 4313 Date d'inscription mercredi 29 mars 2006 Statut Contributeur Dernière intervention 6 janvier 2015 845
26 août 2011 à 07:37
Deux choses :
1- Je ne comprends pas trop la fermeture de parenthèse de ton code à la ligne définissant $result ;
2- Tu oublie le principal : écrire :-)

Sinon en effet le compteur dans mon code me génait mais j'avais la flemme de me creuser la tête à trouver une autre solution... bien vu !
0
Il n'y a pas de parenthèse à la ligne qui définit $result (2e ligne). Par contre, il y en a sur l'une des post-concatenations ( .= ).
Il s'agit d'un ternaire : c'est comme un "if/then/else" mais en condensé.

Ton code ne faisait aucun affichage non plus :p
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Merci pour vos réponses, je dois dire que de chercher des tas de solutions, en faisant du bricolage, je me suis perdu au milieu des lignes de code, pour ça que ça ressemblait à une usine à gaz...

Je me suis donc inspiré de A.Nonymous

$select01 = mysql_query("SELECT * FROM event" . $tblid . " ORDER BY date") or die(mysql_error()); 

  
 $lastDate = '';  

 while($row = mysql_fetch_array($select01)) 
 {  
  if( $row['date'] !== $lastDate )  
  {  
   $lastDate = $row['date'];  
   echo '<br/><br/>' . $row['date'] . ''; 
   echo '<br/>' . $row['event'] . ''; 
  }  
  else 
  { 
   echo '<br/>' . $row['event']; 
  } 
 }  


Tout simple, effectivement, je me suis trop pris la tête inutilement.

Par contre, je n'ai pas utilisé $result, je n'ai pas compris d'abords sa syntaxe, ni son intérêt :s ça semble fonctionner sans.

A un détail près : toutes mes dates sont de 2011, sauf une, qui est 2001.
Toutes s'affichent, avec le groupement que je veux pour les dates communes, mais pas celle de 2001... Je ne vois pas dans le code un quelconque élément excluant une date telle que 2001 en gardant les 2011... Des idées ?
[edit] En fait c'est simplement le 1er enregistrement qui n'est pas pris, ou du moins la 1ere date (issue du ORDER BY). Mais je ne vois pas plus pourquoi...

Pour ce qui est du DISTINCT, apparemment cette fonction arrête de scanner à la première concordance trouvée, or, je peux en avoir plusieurs, donc à priori c'est trop limité dans mon cas.

Merci à tous en tout cas ;)
0
Profil bloqué
27 août 2011 à 13:42
Résolu en haut à droite ;)
0
Bah en fait pas totalement ^^ vu que j'ai toujours pas la 1ere entrée de mon array
0
Profil bloqué
27 août 2011 à 19:01
Tu peux duppliquer la première ligne afin d'éviter le problème. Sinon c'est probablement que tu commences la recherche à la seconde ligne, cad celle d'indice 1, et non 0, or ton élément est à l'indice 0, donc la recherche passe à côté.
0
graffx Messages postés 6506 Date d'inscription jeudi 22 mars 2007 Statut Contributeur Dernière intervention 24 mars 2019 1 973
28 août 2011 à 02:39
bizarre pour ton commentaire sur distinct, je n' ai jamais eu ce souci , enfin je suis content que tu aies trouvé ta solution!
0
bah c'est écrit dans le lien que tu as donné qui explique la fonction ;)
0
Mihawk Messages postés 4313 Date d'inscription mercredi 29 mars 2006 Statut Contributeur Dernière intervention 6 janvier 2015 845
28 août 2011 à 16:17
Hello,
Dans ton while, avant le if, rajoute la ligne suivante :

echo($row['date']);


Et vois si la ligne de 2001 s'affiche : si oui c'est que le problème vient du while qui ne l'affiche pas, sinon c'est que cela vient de la requête MySQL... Mais la vyant je ne comprends pas pourquoi ça fait ça !
0
Désolé, j'ai oublié de le préciser, mais c'est réglé depuis hier soir, en fait j'avais une ligne au-dessus du while qui faisait déjà un fetch_array de select01, sauf que je n'utilisais pas son résultat. C'était une ligne que j'avais faite pour tester un autre truc, et sans cette ligne, j'ai bien ma 1ere entrée ;)

Par contre (vous allez me trouver chiant XD), maintenant que j'arrive à regrouper les events par date, est-ce possible de les trier par heure ? Car pour le moment j'ai :

Date 1
Heure 1 - Event 1
Heure 2 - Event 2

Sauf que si Heure 2 est 10h30 alors que Heure 1 est 17h00, bah dans l'affichage c'est pas terrible :s

Donc je ne sais pas si je peux trier par heure, une fois les events regroupés. J'ai peur que ça fasse beaucoup de conditions qui au final se bloquent les unes les autres.
0
Profil bloqué
28 août 2011 à 18:05
Order by
0
Oui mais j'ai deja un ORDER BY pour trier par date, ensuite, vu que je voulais regrouper par date sans doublon, c'est lorsque le programme scanne l'event suivant, si c'est la meme date, il le met avec. Mais si l'heure du suivant est anterieure au premier, il le met a la suite sans se soucier de l'heure. Mais je vois pas comment refaire un ORDER BY une fois dans la boucle while. Encore si je pouvais connaitre l'heure du suivant au moment le programme fais la boucle, ca irait, je pourrais choisir l'ordre d'affichage. Mais vu que le while se contente de scanner un à un les entrées, je sèche. :s
0
Quel est le format du champ date ? Où est stockée l'heure ?
0
Profil bloqué
29 août 2011 à 11:25
Tu peux faire des select imbriqués sinon
0
Alain_42 Messages postés 5361 Date d'inscription dimanche 3 février 2008 Statut Membre Dernière intervention 13 février 2017 894
29 août 2011 à 10:03
dans ta requette tu mets

....ORDER BY date, heure si ton champ contenant l'heure se nomme ainsi
0
Haaaan je savais pas qu'on pouvais mettre plusieurs arguments derrière un ORDER BY.... lol
Merci beaucoup, voilà de quoi régler mon problème :)
0
Profil bloqué
29 août 2011 à 17:31
^^' pense à mettre résolu en haut à droite !
0
Hmmm, c'est parce que je bigle que je vois pas le bouton "résolu" ? ou parce que je suis pas un utilisateur enregistré ? je peux même pas éditer mon premier message pour mettre résolu dans le titre...
0
Profil bloqué
29 août 2011 à 23:53
Humm en principe tu peux, c'est vers ton titre, sur la droite il me semble ^^'
0
Bah je l'ai "signalé comme résolu", je pense que ce sera fait par un modérateur.
0